AngularJS: привязка к родительскому ngChange [duplicate]

Я использую подкоманду sync hub для автоматизации этого. Хаб псевдонимов как git, поэтому введите команду:

git sync

Это обновляет все локальные ветви, имеющие соответствующую ветку вверх по течению. На странице man:

  • Если локальная ветка устарела, перетащите ее вперед,
  • Если локальная ветка содержит непроверенную работу, предупредите об этом; / g4]
  • Если ветка кажется объединенной, и ее ветвь восходящего потока была удалена, удалите ее.
blockquote>

Он также обрабатывает фиксированные / неработающие незафиксированные изменения в текущей ветке.

Я использовал подобный инструмент под названием git-up , но он больше не поддерживается, а git sync выполняет почти то же самое.

8
задан Robby Allsopp 23 October 2015 в 16:09
поделиться

2 ответа

Вы ответили на свой вопрос в названии! '=' просматривается, а '&' не

  • Где-то вне углового: изменяется значение входного представления
  • следующий цикл дайджест: ng-model изменяется значение и срабатывает ng-change() ng-change добавляет $ viewChangeListener и называется этим же циклом. См .: реализация ngModel.js # L714 и ngChange.js . В то время $scope.searchFilter не обновлялся. Предыдущее значение Console.log
  • следующий цикл дайджест: searchFilter обновляется привязкой данных.

UPDATE: только в качестве POC, для которого вам нужен 1 дополнительный цикл для значение для распространения вы можете сделать следующее. См. Другой anwser (@NewDev для более чистого подхода).

.controller('mainCtrl', function ($scope, $timeout){
    $scope.loadResults = function (){
        $timeout(function(){
           console.log($scope.searchFilter);
        });
    };
});
4
ответ дан aacotroneo 22 August 2018 в 21:07
поделиться
  • 1
    Хороший ответ, я отлаживал Угловой в течение последнего часа, чтобы узнать, что случилось. Можете ли вы объяснить, почему для директивы обновления родительской области требуется дополнительный цикл дайджеста? Это потому, что дайджест начинается с $rootScope и распространяется вниз? Если бы на этом пути был третий ng-change, потребовалось бы больше циклов дайджеста для достижения значения для контроллера? – Artless 16 October 2015 в 20:51
  • 2
    Область выделена, директива не изменяет область действия родителя напрямую. Они способствуют синхронизации = варов, используя знаменитую угловую «привязку данных» .. которая в основном является $watch. Каждый цикл цикла дайджеста выполняет грязную проверку, и когда он обнаруживает изменение, копирует значение «вручную». Таким образом, когда переменная директивы изменяется, ей нужно скопировать $ digest в «родительский» (в то время как & amp; - прямой доступ) – aacotroneo 16 October 2015 в 22:26
  • 3
    Чтобы nitpick, input запускает цикл дайджеста (он не «происходит» во время дайджеста), а в его первой итерации searchModel установлен, а searchChange() (что приводит к loadResults()). Затем на второй итерации searchFilter установлен ... Но это обходное решение очень хаки. – New Dev 16 October 2015 в 23:58
  • 4
    вы правы, когда первый цикл не находится в цикле! (думал о ngModel $ viewValue .. но ngModel не так просто), я отредактирую. О том, как быть взломанным, это вопрос, который был ... «Что происходит?» – aacotroneo 18 October 2015 в 13:46
  • 5
    @AlejandroCotroneo, да, я получил его ... Возможно, было бы лучше сказать, что это POC, чтобы не предполагать, что это, по сути, действительное временное решение. – New Dev 18 October 2015 в 14:05

Причина поведения, как справедливо указано в другом ответе, состоит в том, что двусторонняя привязка не имела возможности изменить внешний searchFilter к моменту времени searchChange() и, следовательно, loadResults() был вызван.

Решение, однако, очень хакерское по двум причинам.

Один, вызывающий (пользователь директивы), не должен знать об этих обходных решениях с помощью $timeout. Если ничего другого, $timeout должно было быть сделано в директиве, а не в контроллере View.

И два - ошибка, также сделанная OP - заключается в том, что использование ng-model происходит с другими " ожидания "пользователями таких директив. Если ng-model означает, что рядом с ним могут использоваться другие директивы, такие как валидаторы, парсеры, форматирующие элементы и слушатели смены вида (например, ng-change). Чтобы поддерживать его правильно, нужно require: "ngModel", а не привязываться к его выражению через scope: {}. В противном случае все будет работать не так, как ожидалось.

Вот как это делается - для другого примера см. официальную документацию для создания пользовательского элемента управления вводом.

scope: true, // could also be {}, but I would avoid scope: false here
template: '<input ng-model="innerModel" ng-change="onChange()">',
require: "ngModel",
link: function(scope, element, attrs, ctrls){
  var ngModel = ctrls; // ngModelController

  // from model -> view
  ngModel.$render = function(){
    scope.innerModel = ngModel.$viewValue;
  }

  // from view -> model
  scope.onChange = function(){
    ngModel.$setViewValue(scope.innerModel);
  }
}

Затем ng-change просто работает автоматически, а также другие директивы, которые поддерживают ngModel, например ng-required.

10
ответ дан New Dev 22 August 2018 в 21:07
поделиться
  • 1
    Я понял, что оставил ключевую информацию из моего примера. Мой внешний ngModel на самом деле является объектом, и я пытаюсь использовать несколько входов внутри директивы для изменения свойств этого объекта, но все равно рассматриваю директиву как один вход. – Robby Allsopp 23 October 2015 в 15:36
  • 2
    @RobbyAllsopp, хорошо, это прекрасно с подходом, который я вам дал. Но ваш подход с $timeout и привязка непосредственно к ngModel неверен и может привести к неожиданным результатам. Например, предположим, что вы хотели использовать ng-model-options с debounce в своей директиве - это не имело бы никакого эффекта. Как я уже сказал, использовать ng-model означает, что вы поддерживаете ngModelController «framework». – New Dev 23 October 2015 в 16:42
  • 3
    Хорошая точка, это испортит некоторые другие вещи с помощью ngModel. Я не вижу пути вокруг $timeout, хотя, если я все еще хочу, чтобы валидация работала, но я мог бы поменять $eval на ngModel.$setViewValue(angular.copy($scope.searchModel)). Я могу переключиться на это, хотя я не в восторге от необходимости копировать весь объект каждый раз, когда что-то меняется – Robby Allsopp 23 October 2015 в 19:27
  • 4
    @RobbyAllsopp, я не уверен, что вы подразумеваете под проверкой. Подтверждение поддерживается с помощью ngModel. На самом деле, я уверен, что с вашим подходом $timeout это не сработало бы, так как изменение напрямую через привязку области привязки обходит анализы и валидаторы. И вам нужно создать новый объект для «изменения», зарегистрироваться. – New Dev 23 October 2015 в 21:29
  • 5
    Что-то изменилось в Angular? Это не работает для меня. Изменения в ngModel изменят ваше текстовое поле, но изменения в текстовом поле не обновляют ngModel. Хотя, onChange определенно называется. Кроме того, после того, как значение текстового поля отличается от ngModel (через ручной ввод), оно больше не обновляется, когда ngModel изменяется в другом месте. Наконец, не будет ли это require: '^ngModel'? Можете ли вы сделать Plunker? – Suamere 31 October 2016 в 21:42
Другие вопросы по тегам:

Похожие вопросы: