加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angularjs – 具有隔离范围的嵌套指令中的双向绑定延迟

发布时间:2020-12-17 17:42:53 所属栏目:安全 来源:网络整理
导读:我有一个控制器包含一个带有隔离范围的指令.每当用户更改指令下拉列表中的值时,我都需要通知控制器有关更改的信息.我这样做是通过为指令提供回调函数,并在指令的下拉列表中的ng-change事件上调用此函数.我不能(也不想)在父控制器中使用手表,因为我只对用户生
我有一个控制器包含一个带有隔离范围的指令.每当用户更改指令下拉列表中的值时,我都需要通知控制器有关更改的信息.我这样做是通过为指令提供回调函数,并在指令的下拉列表中的ng-change事件上调用此函数.我不能(也不想)在父控制器中使用手表,因为我只对用户生成的更改感兴趣.

我的问题是,在调用回调时,控制器范围内的值尚未通过双向绑定更新为指令中的值(我猜这是因为回调是在同一个摘要周期中调用的)已检测到下拉列表模型的更改,但来自父控制器的模型将仅在后续周期中更新.

这是一个说明问题的plunker示例(注意控制台输出):

http://plnkr.co/edit/igW4WiV2niFyrMX2zrjM?p=preview

摘要相关部件的摘录:

控制器:

...
  vm.countryChanged = function() {
    console.log('*** countryChanged callback ***');
    console.log('country:',vm.country); // old value here

    $timeout(function() {
      console.log('country (inside timeout):',vm.country); // new value here
    });
  };
  ...

指示:

...
    template: '<select ng-model="vm.country" ng-change="vm.onChange()"  ' +
              '        ng-options="country for country in vm.countries">' +
              '</select>',scope: {
      country: '=',onChange: '&'
    },...

在父控制器回调中获取更新数据的最正确方法是什么?我可以看到$timeout有帮助,但感觉就像代码味道,并且可能应该有一种方法来强制模型在父控制器上更新.

解决方法

I guess this is because the callback is called in the same digest-cycle where the changes on the dropdown’s model has been detected,but the models from the parent controller will only be updated in the subsequent cycles.

你是对的.在ng-change指令评估其Angular表达式之后,将指令范围的值更新为父控制器的观察程序在摘要周期触发.

在指令和父控制器之间共享公共对象引用是使其工作的一种方法.由于控制器和指令共享相同的引用,因此指令和父控制器都会立即看到任何更改.

另一种方法是将新值公开为on-change函数的本地参数:

<country-chooser 
    country="vm.country" 
    country-change="vm.countryChange($event)">
</country-chooser>

要么

<country-chooser 
    country="vm.country" 
    country-change="vm.country=$event">
</country-chooser>

在指令中:

app.directive('countryChooser',function() {
  return {
    template: `<select ng-model="$ctrl.country"
                       ng-change="$ctrl.countryChange({'$event': vm.country})"
                       ng-options="country for country in $ctrl.countries">
              </select>
              `,scope: {
      country: '<',countryChange: '&'
    },bindToController: true,controllerAs: '$ctrl',

在父控制器中:

vm.countryChange = function(country) {
      console.log('*** countryChange callback ***');
      console.log('country:',country);
  };

这样,父控制器内的函数不需要在双向绑定上等待观察者的摘要周期,以将值从指令范围更新到父控制器范围.

DEMO on PLNKR.

AngularJS v1.5组件并使它们成为Angular2准备好的

app.component('countryChooser',{
    template: `<select ng-model="$ctrl.country"
                       ng-change="$ctrl.countryChange({'$event': vm.country})"
                       ng-options="country for country in $ctrl.countries">
              </select>
              `,bindings: {
      countries: '<'
      country: '<',countryChange: '&'
    }
});

AngularJS v1.5引入了components,以便更容易地过渡到Angular2.

为了更容易过渡到Angular2,请避免双向(=)绑定.而是使用单向<约束和表达&捆绑. 在Angular2中,双向绑定语法实际上只是属性绑定和事件绑定的语法糖.

<country-chooser [(country)]="vm.country">
</country-chooser>

Angular2去糖双向绑定到此:

<country-chooser [country]="vm.country" (countryChange)="vm.country=$event">
</country-chooser>

有关更多信息,请参阅@Angular Developer Guide – Template Syntax (two-way)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读