如何在AngularJS中手动将值传播到指令的父作用域?

时间:2017-10-09 14:57:18

标签: javascript angularjs angular-ui-typeahead

My AngularJS typeahead FaveDirective需要将单个值绑定到父作用域,并在该值发生更改时调用update函数:

父html:

<div class="parent-controller-scope ng-scope">
  <my-fave-picker favorite="parent.favorite" on-change="parent.update()">
</div>

Fave picker指令模板:

<input 
    type="text" 
    ng-model="vm.favorite" 
    typeahead-on-select="vm.onChange()"
    ng-init="vm.loadTypeaheadValues()"
    placeholder="Pick your favorite Swift"
    uib-typeahead="name for name in ::vm.TypeaheadValues | filter:$viewValue"
    class="form-control">     

Fave picker指令代码:

(function (angular, _) {
    'use strict';

    angular
        .module('favorite')
        .directive('MyFavePicker', function() {
            return {
                restrict: 'E',
                templateUrl: 'fave-picker-template.html',
                scope: {
                    favorite: '=',
                    onChange: '&'
                },
                controllerAs: 'vm',
                bindToController: true,
                controller: 'FavePickerController'
            };
        })
        .controller('FavePickerController', function() {
             // etc.
        });

}(angular, _));

这几乎正常;提交预先输入时,它会按预期在父作用域上调用update()。问题是在之前发生favorite的最新值传播到父作用域。换句话说,如果typeahead有可能的值["Taylor Swift", "Jonathan Swift"]并且我键入“Tay”然后按Enter键从下拉列表中选择值,那么在执行typeahead-on-select回调时,我有以下值:

vm.favorite = "Taylor Swift"    
parent.favorite = "Tay"

因此parent.update()函数的值为parent.favorite(“Tay”而不是“Taylor Swift”)的错误值。

我可以想到一些不好的方法,但是这样做的正确方法是什么,以便在调用vm.favorite之前将parent.favorite()的更改传播回父范围

请注意,在我的情况下,以下情况是不可能的:

  • 继承父范围而不是使用隔离范围
  • favorite作为参数传递给updateon-change="parent.update(favorite)"
  • 在调用dir.onChange()
  • 之前在parent.update()设置超时

1 个答案:

答案 0 :(得分:0)

避免在组件中使用双向'='绑定来传播值。而是使用单向'<'绑定输入和表达式'&',绑定输出:

<my-fave-picker  favorite="parent.favorite"
    on-change="parent.favorite=$value; parent.update($value)">
</my-fave-picker> 
app.directive('MyFavePicker', function() {
    return {
        restrict: 'E',
        templateUrl: 'fave-picker-template.html',
        scope: {
            ̶f̶a̶v̶o̶r̶i̶t̶e̶:̶ ̶'̶=̶'̶,̶ 
            favorite: '<',
            onChange: '&'
        },
        controllerAs: 'vm',
        bindToController: true,
        controller: 'FavePickerController'
    };
})

在组件模板中:

<input 
    type="text" 
    ng-model="vm.favorite"
    ng-change="vm.onChange({$value: vm.favorite})"
    typeahead-on-select="vm.onChange({$value: vm.favorite})"
    ng-init="vm.loadTypeaheadValues()"
    placeholder="Pick your favorite Swift"
    uib-typeahead="name for name in ::vm.TypeaheadValues | filter:$viewValue"
    class="form-control"
/>     

通过应用表达式中的值'&',绑定,该值立即传播。对于双向'='绑定,该值在摘要周期后传播。

有关详细信息,请参阅