简体   繁体   English

当父元素更改时,AngularJS更新子组件

[英]AngularJS updating child component when parent element changes

I'm working on a an existing Angular application (1.4.3) and I'm trying to break things up into components that can be more re-usable and allow for a better upgrade path to Angular 2. 我正在开发一个现有的Angular应用程序(1.4.3),并且试图将它们分解为更可重用的组件,并允许更好地升级到Angular 2。

I've got a child component that takes an input from the parent and displays a table. 我有一个子组件,它从父组件接收输入并显示一个表。 In the table, that input has been plugged into various mathematical formulas and displays each of the resulting numbers. 在表中,该输入已插入到各种数学公式中,并显示每个结果数字。 My problem is that when I update the parent value, the child component doesn't reflect the update. 我的问题是,当我更新父值时,子组件无法反映更新。 I thought bindToController was supposed to make is so that I didn't have to put a watch on the input. 我以为bindToController应该做的是,这样我就不必在输入上放一块手表了。 I also noticed things get weird if I'm using ng-model vs ng-bind in the template. 我还注意到,如果我在模板中使用ng-model vs ng-bind ,事情会变得很奇怪。 Can anyone explain to me what's going on here and why? 谁能向我解释这里发生了什么,为什么?

Here's an example. 这是一个例子。 http://jsbin.com/yoqenahini/1/edit?html,js,output http://jsbin.com/yoqenahini/1/edit?html,js,输出

The reason the value isn't being updated in the child directive is that you are assigning the value to a new variable here: 子指令中的值未更新的原因是,您正在此处将值分配给新变量:

this.item2 = this.item + 25;

and then your input is binding to the new value item2 . 然后您的输入将绑定到新值item2

Here's a fork of your code, I added a second input in the child directive that binds to item . 这是您的代码的一部分,我在绑定到item的child指令中添加了第二个输入。 When you change the parent value it also changes. 当您更改父值时,它也会更改。

http://jsbin.com/carolitajo/1/edit?html,js,output http://jsbin.com/carolitajo/1/edit?html,js,输出

So if you just use the item property directly in your child controller you should be all set. 因此,如果您仅在子控制器中直接使用item属性,则应该一切就绪。 Angular isn't going to re-run your assignment to item2 every time the parent value changes. 每次父值更改时,Angular都不会重新运行对item2的分配。

I ended up just adding a $watch on the input after coming across this comment chain. 碰到这个评论链后,我最终只是在输入中添加了一个$watch It's working great. 效果很好。 I was just overly concerned about watches. 我只是太在意手表。

http://teropa.info/blog/2015/10/18/refactoring-angular-apps-to-components.html#comment-2446653932 http://teropa.info/blog/2015/10/18/refactoring-angular-apps-to-components.html#comment-2446653932

In reality, this works great and still feels better because the watch is inside the component opposed to on the page controller. 实际上,由于手表位于与页面控制器相对的组件内部,因此效果很好,但感觉仍然更好。

There is a quirk though if you are using controllerAs which I had to discover here. 如果您使用的是controllerAs,那会有一个奇怪的地方,我必须在这里发现。 https://toddmotto.com/digging-into-angulars-controller-as-syntax/#ironing-a-quirk https://toddmotto.com/digging-into-angulars-controller-as-syntax/#ironing-a-quirk

what about 关于什么

$scope.$broadcast( "parentCtrlUpdateChild", args );

and then 接着

in your child 在你的孩子

$scope.$on("parentCtrlUpdateChild", function(event, args) {
  ...
});

see Todd Motto's explanation https://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/ 请参阅Todd Motto的说明https://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/

see this Bin I prepared for you 看到我为你准备的垃圾桶

http://jsbin.com/zinuqikemo/edit?html,js,output http://jsbin.com/zinuqikemo/edit?html,js,输出

function parent() {
  return {
    restrict: 'E',
    template: '<div><div><input type="text" ng-model="item"/></div><ng-transclude></ng-transclude></div>',
    controllerAs: 'pctrl',
    transclude: true,
    controller: function($scope) {
      $scope.item = 25;
      $scope.hola = function() {
        $scope.item = $scope.item + 1;
        $scope.$broadcast('hola', $scope.item);
      };
    }
  };
}

function child() {
  return {
    restrict: 'E',
    scope: {
      item: '='
    },
    template: '<div><div><input type="text" ng-model="item2"/><div></div></div></div>',
    bindToController: true,
    controllerAs: 'cctrl',
    controller: function($scope) {      
      $scope.$on('hola', function (event, args) {
        $scope.item2 = args + 25;
      });
    }
  };
}

and in your HTML just add this 并在您的HTML中添加

<button ng-click="hola()">HOLA</button>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM