2013-12-17 4 views
5

Использование Angular 1.0.7:

У меня есть директива, которая предназначена для отображения стилизованного флажка.

See plunkr here.

Иногда (и не всегда) мое наблюдающее обновление оленьей кожи один переменных увидеть мой прицел:

Вот неудача последовательность:

  • Foo
  • бар
  • все
  • foo
  • бар

enter image description here

Интересно, почему происходит обновление оленьей кожи.

+0

им не уверен, что я следую вашей проблеме? все работает для меня, когда я нажимаю на foo, каждый раз, когда не сработает ... –

+0

это то, где *** иногда *** усложняет ситуацию, позвольте мне попытаться найти неудачную последовательность. – apneadiving

+0

получил один, добавленный под вопрос – apneadiving

ответ

2

Это был очень интересный вопрос, поэтому проблема с комбинацией ваших щелкнул обработчик и предпочтения.электронная почта часы:

angularjs код:

//https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js line 4510 
scope.$watch(function parentValueWatch() { 
    var parentValue = parentGet(parentScope); 

    if (parentValue !== scope[scopeName]) { 
     // we are out of sync and need to copy 
     if (parentValue !== lastValue) { 
      // parent changed and it has precedence 
      lastValue = scope[scopeName] = parentValue; 
     } else { 
      // if the parent can be assigned then do so 
      parentSet(parentScope, parentValue = lastValue = scope[scopeName]); 
     } 
    } 
    return parentValue; 
}); 
break; 

Вы начинаете с нажатием на обув + бар и мы имеем:

all: true 
foo: true 
bar: true 

Нажмите на тумблер все:

//by this code 
var new_val = toggled_input_value(); 
$scope.model = new_val; 

$ scope.model является сфера [имя_области] из приведенного выше кода, так что сфера [имя_области] = ложь и LastValue = верно, parentValue = истина (они будут изменения после того, как $ переваривать бег)

$scope.clicked({ value: new_val }); 

будет звоните

$scope.toggleAll = function(new_value){ 
    if (new_value){ 
    $scope.preferences.email.foo = true; 
    $scope.preferences.email.bar = true; 
    } 
    else{ 
    $scope.preferences.email.foo = false; 
    $scope.preferences.email.bar = false;  
    } 
} 

так,

all: true - $digest have not been run 
foo: false 
bar: false 

и начинают $ переваривать ... первый звонок будет:

$scope.$watch('preferences.email', function(new_value){ 
    var bool = new_value.foo && new_value.bar; 
    $scope.preferences.all = bool; 
}, true); 

так,

all: false 
foo: false 
bar: false 

это проблема, потому что на следующий parentValueWatch вызова мы получим:

parentValue = false //$scope.preferences.all 
scope[scopeName] = false //$scope.model 
lastValue = true 

так, parentValue === Сфера [имя_области] , и lastValue не были обновлены ... это ошибка:

, когда вы будете чанг е $ scope.preferences.all к истинному, вы получите

$scope.preferences.all === lastValue //true 

и вызвать

// if the parent can be assigned then do so 
parentSet(parentScope, parentValue = lastValue = scope[scopeName]); 

так, $ scope.preferences.all станет ложным, а не истинным

вы можете посмотреть на это здесь http://plnkr.co/edit/YEHqA101YwWKDvK6odFf?p=preview (console.trace)

+0

Это отличный ответ ... – apneadiving

+0

ОК, так что его угловая ошибка? – apneadiving

+0

моя проблема в том, что если я использую обратный вызов, контроллер по-прежнему несет не обновляемый объект. Вот почему я использовал $ watch, что тоже не очень хорошо :) – apneadiving

2

Существует код ТОН, который у вас есть, что вам не нужно. Некоторая часть этого кода, не совсем уверенная, какая линия, вмешивается. В основном вам не нужно вручную устанавливать модель на флажке, когда вы устанавливаете ng-model='model' в свой шаблон, это все, что вам нужно!

Итак, вот рабочая вилка вашего кода, которая работает: http://plnkr.co/edit/CzhiAVEAuDtiL2QO95Za, и, как вы можете видеть, я удалил почти все, что вы делали относительно модели, так как все автоматическое.

Давайте подведем итог, что мы сделали:

  1. удалили предварительно компилировать код, если вам не нужно имя, которое будет определена до компиляции? не знаю почему.
  2. нет необходимости в функциях входных значений, это правда или неверно? Это автоматически выполняется моделью.
  3. $ scope.select должен просто переключать значение модели, все остальное автоматически.
  4. удаляет, функцию инициализации, значение модели автоматически устанавливаются в любом случае
  5. удалило глубоких часов внутри директивы, вам не нужно DEEP смотреть здесь, как вы передаете его самые низкие значения, и это не беспокоит другие значения. Внешняя функция переключения - единственное, что беспокоит глубокое наблюдение.

упрощенный код директивы:

app.directive("uuCheckbox", function() { 
return { 
    restrict: "A", 
    transclude: true, 
    scope: { 
    model: '=', 
    clicked: '&' 
    }, 
    template: "<div ng-click='select()'>" + 
    "<span ng-class='{ checked: model }'></span>" + 
    "<input class='hidden' value='true' type='checkbox' ng-model='model'>" + 
    "<span ng-class='{red: model}' ng-transclude></span>" + 
    "</div>", 
    compile: function(elmt, tAttrs) { 
    return function($scope, element, attrs) { 
     element.find('input').attr('name', attrs.name); 
     var on_change = function(new_value) { 
     $scope.clicked({ value: new_value }); 
     }; 
     $scope.$watch('model', on_change); 
     $scope.select = function() { 
     $scope.model = !$scope.model; 
     }; 
    }; 
    } 
}; 
}); 
+0

Мне нужна предварительная компиляция, потому что флажок должен быть отмечен, если присутствует проверенное свойство html, то есть один из параметров, которые я передаю так же, как имя (но удалено в моем примере, чтобы показать минимальный код) – apneadiving

+0

, а флажок не просто true/false, он может иметь любое значение или false (так что да, мне нужно получить значение, которое я передаю в args) – apneadiving

+0

интересно, как передать правильное значение модели без взлома ввода val – apneadiving

Смежные вопросы