如何避免双向绑定的摘要周期延迟

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何避免双向绑定的摘要周期延迟相关的知识,希望对你有一定的参考价值。

当双向数据绑定被触发时Angularjs?

在AngularJS应用程序中,我有一个父指令和一个子指令。

parentDirective

angular
  .module('myApp')
  .directive('customForm', function(customService, apiV1, Constants, $timeout) {
    return {
      restrict: 'E',
      scope: {
        param1: '=',
        param2: '=?',
        boolean1: '@?'
      },
      template,
      link: function(scope, parentController) {
      scope.data = customService.newClient;
      //some stuff...

childDirective JS:

angular
  .module('myApp')
  .directive('customToolForm', function () {
    return {
      restrict: 'E',
      scope: {
        name: '=',
        city: '=',
        postalCode: '='
      },
      template,
      controller: function ($scope, $rootScope, Constants, apiV1, customService) {

     $scope.doSomethingWithPostalCode = function() {
         $scope.$parent.doSomethingWithPostalCode();
     }
     //some stuff...

parentDirective html piece:

<address-client-creation name="data.client.name" city="data.client.city"
                         postal-code="data.client.postalCode">
</address-client-creation>

childDirective HTML piece:

 <input maxlength="5" type="text" data-ng-model="postalCode"
        data-ng-change="doSomethingWithPostalCode();">

我的问题是:

当从childDirective触发方法doSomethingWithPostalCode时,子进程中的postalCode的值与父进程的client.postalCode不同,但是在方法的末尾。

似乎更新父值的双向绑定事件发生在函数调用之后

所以我的问题是在调用方法之前确保$ parent范围更新的最佳方法是什么?

答案

如何避免双向绑定的摘要周期延迟

AngularJS框架通过向子作用域添加一个观察者来实现双向('=')绑定,该子作用域将数据从子作用域传输到父作用域。观察者需要摘要周期来检测变化并进行转移。

更现代的方法是使用单向("<")绑定输入和表达式("&")绑定输出:

app.directive('customToolForm', function () {
    return {
      restrict: 'E',
      scope: {
        name: '<',
        city: '<',
        ̶p̶o̶s̶t̶a̶l̶C̶o̶d̶e̶:̶ ̶'̶=̶'̶
        postalCode: '<',
        postalCodeChange: '&',
      },
      template: `
          <input maxlength="5" type="text" data-ng-model="postalCode"
                 data-ng-change="doSomethingWithPostalCode(postalCode);">
      `,
      controller: function ($scope, $rootScope, Constants, apiV1, customService) {

     $scope.doSomethingWithPostalCode = function(postalCode) {
         ̶$̶s̶c̶o̶p̶e̶.̶$̶p̶a̶r̶e̶n̶t̶.̶d̶o̶S̶o̶m̶e̶t̶h̶i̶n̶g̶W̶i̶t̶h̶P̶o̶s̶t̶a̶l̶C̶o̶d̶e̶(̶)̶;̶
         $scope.postalCodeChange({$event: postalCode});
     }
     //some stuff...

用法:

<custom-form-tool 
    name="data.client.name" city="data.client.city"
    postal-code="data.client.postalCode"
    postal-code-change="data.client.postalCode=$event; doSomething($event)"
>
</custom-form-tool>

使用表达式("&")绑定会立即使事件数据可用于父控制器。

它还使Angular 2+的迁移路径更容易。

有关更多信息,请参阅

另一答案

我找到的解决方案是在childDirective中使用$watch

    /**
     * Using $watch instead of data-ng-change ensure that bindings are updated
     */
    $scope.$watch('postalCode', function() {
       $scope.$parent.doSomethingWithPostalCode();
    });

因此,删除子指令输入中的the data-ng-change

 <input maxlength="5" type="text" data-ng-model="postalCode">

在$ watch方法中调试时,我可以验证父$ scope已经更新。

不确定它是真正的解决方案还是更像是黑客攻击。

以上是关于如何避免双向绑定的摘要周期延迟的主要内容,如果未能解决你的问题,请参考以下文章

vue如何避免变量赋值后双向绑定

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

Vue生命周期与单向、单次、双向绑定

Vue.js线程机制问题还是数据双向绑定有延迟的问题

angularJS使用ocLazyLoad实现js延迟加载

是否有一个生命周期钩子在组件初始化后运行一次,但也在加载双向绑定后运行?