AngularJS对象字段不是从孩子的指令更新 [英] AngularJS object field not updating from child directive

查看:321
本文介绍了AngularJS对象字段不是从孩子的指令更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个父控制器 A ,谁的范围包含的对象重新presenting其状态。所以,我可以访问 state.status A 的范围,以更新其状态。

我有一个孩子的指令, B ,谁拥有绑定到字段 A 的状态对象。这让我更新的 A B

状态

下面是简化code为我控制器 A

  angular.module(对myApp)。控制器('A',函数($范围){    $ scope.state = {
        状态:全部
    };
    函数DoSomething的(){
        的console.log(state.status);
    }});

和用于指示 B

  angular.module('对myApp')。指令('B',函数(){    返回{
        templateUrl:B.html',
        范围: {
            selectedStatus:'=地位,
            的onChange:'=的onChange
        },
        链接:功能(范围,元素,ATTRS){
            scope.setStatus =功能(状态){
                scope.selectedStatus =状态;
                scope.onChange();
            };
        }
    }});

在DOM:

 < B状态=上变化=DoSomething的/&GTstate.status

当我称之为 setStatus()从我的指令中 B ,我希望我所提出的修改对象由 DoSomething的()被调用的时候被传播。但是,的console.log()输出是旧的价值,不是我只是它更新到。在修改完成,只是不够快。

我试过打电话给 $范围。$适用()但是它抱怨一个 $范围之内。$适用()通话了。 (

什么是对付它的最好方法?


解决方案

依我看你是一个有点困惑是如何工作的。

当你做的东西像状态=state.status和更改状态的指令里面,变化将只执行摘要周期后应用,但在你的情况下,您尝试输出 state.status 前完成消化,所以它不使用同步的值。

有解决这几个方面:


  1. 通话 scope.onChange $超时

  2. 通过完整的对象状态而不是 state.status

  3. 使用范围。$父访问,可以定义父范围状态对象

\r
\r

angular.module(对myApp,[])。指令('BB' ,功能($超时){\r
  返回{\r
    模板:'< D​​IV>< D​​IV NG点击=setStatus1(\\'状态1 \\')大于1。所选状态:{{selectedStatus}}< / DIV>< D​​IV NG点击=setStatus2(\\'STATUS2 \\')大于2。所选状态:{{selectedStatus}}< / DIV>< D​​IV NG点击=setStatus3(\\'STATUS3 \\')→3。所选状态:{{selectedStatus}}< / DIV>< / DIV>,\r
    范围: {\r
      selectedStatus:'=地位,\r
      的onChange:'=的onChange',\r
      状态:'='\r
    },\r
    链接:功能(范围,元素,ATTRS){\r
      scope.setStatus1 =功能(状态){\r
        的console.log('setstatus1');\r
        scope.selectedStatus =状态;\r
        $超时(函数(){\r
          scope.onChange();\r
        });\r
      };\r
      scope.setStatus2 =功能(状态){\r
        的console.log('setstatus2');\r
        scope.selectedStatus =状态;\r
        scope.state.status =状态;\r
        scope.onChange();\r
      };\r
      scope.setStatus3 =功能(状态){\r
        的console.log('setstatus3');\r
        scope.selectedStatus =状态;\r
        。范围$ parent.state.status =状态;\r
        scope.onChange();\r
      };\r
    }\r
  }\r
\r
})。控制器('A',函数($范围){\r
\r
  $ scope.state = {\r
    状态:全部\r
  };\r
  $ scope.doSomething = DoSomething的;\r
\r
  函数DoSomething的(){\r
    的console.log('DoSomething的:',$ scope.state.status);\r
  }\r
\r
});

\r

<脚本数据需要=angular.js@1.4.0-rc .1数据semver =1.4.0-RC.1SRC =的https://$c$c.angularjs.org/1.3.8/angular.js>&下; /脚本>\r
< D​​IV NG-应用=对myAppNG控制器=A>\r
  < BB状态=state.status状态的变化=DoSomething的&GT =状态;< / BB>\r
  {{州}}\r
< / DIV>

\r

\r
\r

I have a parent controller A, who's scope contains an object representing its state. So I can access state.status from A's scope to update its status.

I have a child directive, B, who has a binding to a field in A's status object. This allows me to update A's state from B.

Here's the simplified code for my controller A:

angular.module("myApp").controller('A', function($scope){

    $scope.state = {
        "status": "All"
    };


    function doSomething() {
        console.log(state.status);
    }

});

And for the directive B:

angular.module('myApp').directive('B', function () {

    return {
        templateUrl: 'B.html',
        scope: {
            selectedStatus: '=status',
            onChange: '=onChange'
        },
        link: function (scope, element, attrs) {
            scope.setStatus = function(status) {
                scope.selectedStatus = status;
                scope.onChange();
            };
        }
    }

});

In the DOM:

<B status="state.status" on-change="doSomething" />

When I call setStatus() from within my directive B, I expect the changes I've made to the object to be propagated by the time doSomething() is called. However, the console.log() output is of the old value, not what I've just updated it to. The change is made, just not fast enough.

I've tried to call $scope.$apply() however it complains that it's within a $scope.$apply() call already. :(

What's the best way to deal with this?

解决方案

Methinks you are a bit confused about how this works.

When you do something like status="state.status" and change status inside a directive, changes will be applied only after executing the digest cycle, but in your case you try to output state.status before finishing the digest, so it doesn't use the synchronized value.

There are a few ways to solve this:

  1. call scope.onChange inside $timeout
  2. pass full object state instead state.status
  3. use scope.$parent for access to parent scope where you define state object

angular.module("myApp", []).directive('bb', function($timeout) {
  return {
    template: '<div><div ng-click="setStatus1(\'status1\')">1. Selected status: {{selectedStatus}}</div><div ng-click="setStatus2(\'status2\')">2. Selected status: {{selectedStatus}}</div><div ng-click="setStatus3(\'status3\')">3. Selected status: {{selectedStatus}}</div></div>',
    scope: {
      selectedStatus: '=status',
      onChange: '=onChange',
      state: '='
    },
    link: function(scope, element, attrs) {
      scope.setStatus1 = function(status) {
        console.log('setstatus1');
        scope.selectedStatus = status;
        $timeout(function() {
          scope.onChange();
        });
      };
      scope.setStatus2 = function(status) {
        console.log('setstatus2');
        scope.selectedStatus = status;
        scope.state.status = status;
        scope.onChange();
      };
      scope.setStatus3 = function(status) {
        console.log('setstatus3');
        scope.selectedStatus = status;
        scope.$parent.state.status = status;
        scope.onChange();
      };
    }
  }

}).controller('A', function($scope) {

  $scope.state = {
    "status": "All"
  };
  $scope.doSomething = doSomething;

  function doSomething() {
    console.log('doSomething: ', $scope.state.status);
  }

});

<script data-require="angular.js@1.4.0-rc.1" data-semver="1.4.0-rc.1" src="https://code.angularjs.org/1.3.8/angular.js"></script>
<div ng-app="myApp" ng-controller="A">
  <bb status="state.status" state="state" on-change="doSomething"></bb>
  {{state}}
</div>

这篇关于AngularJS对象字段不是从孩子的指令更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆