在以下示例 ( plunker ) 中,ui-router 状态路由到具有数据对象和替换方法的应用程序组件,该方法使用给定值将该对象替换为新对象。在其模板中,它具有:
- 通过回调绑定 ('&')触发替换方法的编辑器组件
- 一个显示组件,它通过单向绑定('<')接收数据对象,在 $onChanges 生命周期钩子被触发时制作本地副本,并显示对象的内容
一切正常,如预期的那样:-)
angular
.module('app', ['ui.router'])
.config(($urlRouterProvider, $stateProvider) => {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('root', {
url: '/',
component: 'app'
});
})
.component('app', {
controller: function () {
this.data = { name: 'initial' };
this.replace = (value) => { this.data = { name: value }; };
},
template: `
<editor on-replace="$ctrl.replace(value)"></editor>
<display data="$ctrl.data"></display>
`
})
.component('editor', {
bindings: {
onReplace: '&'
},
controller: function () {
this.replace = (value) => this.onReplace({value});
},
template: `
<input type="text" ng-model="value">
<button ng-click="$ctrl.replace(value)"> replace object </button>
`
})
.component('display', {
bindings: {
data: '<'
},
controller: function () {
this.$onChanges = (changes) => {
if (changes.data) {
this.data = Object.assign({}, this.data);
}
};
},
template: `
<p> value : {{ $ctrl.data.name }} </p>
`
});
我对以下第二个示例(plunker)有疑问。这是完全相同的设置,只是应用程序组件不再管理数据本身,而是通过定义为 ui-router 状态解析的单向绑定 ('<')接收数据对象(如在评论中可以看到,我使用全局对象和方法进行了测试,并通过服务进行了交互)。当这个解析的对象被重新分配时,我期待应用程序组件的 $onChanges 钩子被触发(当应用程序组件的数据对象被重新分配时,显示组件也是如此),但事实并非如此。有人有解释吗?
let data = { name: 'initial' };
const replace = (value) => { data = { name: value }; };
angular
.module('app', ['ui.router'])
/*.factory('DataService', function () {
let data = { name: 'initial' };
return {
getData: () => data,
replace: (value) => { data = { name: value }; }
};
})*/
.config(($urlRouterProvider, $stateProvider) => {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('root', {
url: '/',
component: 'app',
resolve: {
data: () => data /*(DataService) => DataService.getData()*/
}
});
})
.component('app', {
bindings: {
data: '<'
},
controller: function (/*DataService*/) {
this.$onChanges = (changes) => {
if (changes.data) {
this.data = Object.assign({}, this.data);
}
};
this.replace = (value) => { replace(value); }; /*(value) => { DataService.replace(value); };*/
},
template: `
<editor on-replace="$ctrl.replace(value)"></editor>
<display data="$ctrl.data"></consumer>
`
})
.component('editor', {
bindings: {
onReplace: '&'
},
controller: function () {
this.replace = (value) => this.onReplace({value});
},
template: `
<input type="text" ng-model="value">
<button ng-click="$ctrl.replace(value)"> replace object </button>
`
})
.component('display', {
bindings: {
data: '<'
},
controller: function () {
this.$onChanges = (changes) => {
if (changes.data) {
this.data = Object.assign({}, this.data);
}
};
},
template: `
<p> value : {{ $ctrl.data.name }} </p>
`
});