绑定到vm中断引用

时间:2017-07-07 06:12:28

标签: javascript angularjs

扩展绑定到var vm = this的控制器无法读取组件bindings

中的绑定值

在示例中,区别在于(单击按钮显示实体)

app.controller('ThisBasicCtrl', function() {
  this.click = function() {
    this.text = this.entity;
  };
});
app.controller('VmBasicCtrl', function() {
  var vm = this;
  vm.click = function() {
    vm.text = vm.entity; // here entity is undefined
  };

  vm.clickThatWorks = function() {
    this.text = this.entity // 'NOT really VM but shows the value';
  }
});

var app = angular.module('app', []);

app.controller('MainCtrl', function() {
  var vm = this;
  vm.entity = {
    name: 'test'
  };
});

app.controller('ThisBasicCtrl', function() {
  this.click = function() {
    this.text = this.entity;
  };
});

app.component('thisExtendedComponent', {
  template: '<button ng-click="vm.click()">This controller</button><div>{{vm.text}}</div>',
  controller: 'ExtendedCtrl',
  controllerAs: 'vm',
  bindings: {
    entity: '<'
  }
});

app.controller('ExtendedCtrl', function($controller) {
  angular.extend(this, $controller('ThisBasicCtrl'));
});

app.controller('VmBasicCtrl', function() {
  var vm = this;
  vm.click = function() {
    vm.text = vm.entity; // here entity is undefined
  };

  vm.clickThatWorks = function() {
    this.text = this.entity // 'NOT really VM but shows the value';
  }
});

app.component('vmExtendedComponent', {
  template: '<button ng-click="vm.click()">VM controller</button><div>{{vm.text}}</div>',
  controller: 'VmExtendedCtrl',
  controllerAs: 'vm',
  bindings: {
    entity: '<'
  }
});

app.controller('VmExtendedCtrl', function($controller) {
  angular.extend(this, $controller('VmBasicCtrl'));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
<div ng-app="app" ng-controller="MainCtrl as vm">
  <div style="border: 1px solid;">
    <h5>
Extends <i style="color:orange">this</i> controller
</h5>
    <this-extended-component entity="vm.entity"></this-extended-component>
  </div>
  <br>
  <div style="border: 1px solid;">
    <h5>
Extends <i style="color:orange">VM</i> controller
</h5>
    <vm-extended-component entity="vm.entity"></vm-extended-component>
  </div>
</div>

1 个答案:

答案 0 :(得分:0)

Extend将复制函数中的参考...

thisExtendedComponent组件上,您正在扩展ThisBasicCtrl,并且其click功能会在功能中重新拥有自己,但 vmExtendedComponent组件正在扩展VmBasicCtrl控制器,在click函数内部,它重新构成VmBasicCtrl控制器而不是自己。

因此,当您运行vm函数时,vmExtendedComponent的变量是VmBasicCtrl,但click中的变量变化。

<强> 演示

在下面的示例中,使用相同的控制器创建了两个组件。控制器具有clickThatWorksctrl功能。按下按钮组件时,将在控制器上记录click变量。主要的区别是clickThatWorks func重新定义一个变量,但var app = angular.module('app', []); app.controller('MainCtrl', function() { var vm = this; vm.entity = { name: 'test' }; }); app.controller('VmBasicCtrl', function() { var vm = this; vm.ctrl = 'vmbasic'; vm.click = function() { console.log(vm.ctrl, vm.entity); // this is referancing vmBasic only vm.text = vm.entity; // here entity is undefined }; vm.clickThatWorks = function() { console.log(this.ctrl, this.entity); // this is referancing ownself this.text = this.entity // 'NOT really VM but shows the value'; } }); app.component('vmExtendedComponent1', { template: '<span>click Example</span> <br><button ng-click="vm.click()">VM controller</button><div>{{vm.text}}</div>', controller: 'VmExtendedCtrl', controllerAs: 'vm', bindings: { entity: '<' } }); app.component('vmExtendedComponent2', { template: '<span>clickThatWorks Example </span><br><button ng-click="vm.clickThatWorks()">VM controller</button><div>{{vm.text}}</div>', controller: 'VmExtendedCtrl', controllerAs: 'vm', bindings: { entity: '<' } }); app.controller('VmExtendedCtrl', function($controller) { angular.extend(this, $controller('VmBasicCtrl')); this.ctrl = 'vmextended'; });重新设置了自己。

运行并查看结果。

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
<div ng-app="app" ng-controller="MainCtrl as vm">
    <vm-extended-component1 entity="vm.entity"></vm-extended-component1>
    <vm-extended-component2 entity="vm.entity"></vm-extended-component2>
</div>
<br>