in this plunk我已经为我上周面临的问题做了一个演示。代码段包含引导标签,其中包含两个不同的页面 - 第1页和第2页,它们使用的是相同的控制器。 Page1 有ng-repeat,当我们从那里点击选项时,它在控制器函数vm.edit(selected_variable)中命中,Page2有一个简单的输入框,其中包含 ng -model =" vm.name" 即可。我的问题是当vm.edit函数更新时,ng-name没有更新或替换为值。我可以使用 rootScope 解决这个问题,但我不想使用rootScope。我只想避免使用rootScope,并希望使用 vm 。
我的代码示例:
第1页:
<div ng-controller="appCtrl as vm">
<div>
<ul>
<li ng-repeat="list in vm.list track by $index">
<button type="button" class="btn-u btn-brd btn-u-none" ng-click="vm.edit(list, $index)" data-toggle="tab" href="#page2">
{{ list.name }}
</button>
</li>
</ul>
</div>
</div>
第2页:
<div ng-controller="appCtrl as vm">
<input type="text" ng-model="vm.name">
</div>
控制器:
vm.edit = function(listItem, index) {
vm.name = listItem.name;
console.log(vm.name);
};
编辑功能会更新第1页中的 vm.name ,但它并未在第2页中反映出来。无法解决这个问题,任何想法?
答案 0 :(得分:3)
为了在控制器之间进行通信,您可以使用 $ broadcast 事件来传输数据。这是经过编辑的Plunker。
在 vm.edit 函数内注册广播并在同一个控制器中监听事件:
vm.edit = function(listItem, index) {
$rootScope.$broadcast("vm name: changed", listItem.name);
};
$scope.$on("vm name: changed", function(evt, obj){
vm.name = obj;
});
另外,不要忘记将 $ rootScope 依赖项添加到您的控制器:
app.controller('appCtrl', function($scope, $rootScope) {...});
注意: 此处 $ rootScope 仅用于触发事件,但不用于存储值。
答案 1 :(得分:1)
page1.html
<div ng-controller="appCtrl">
<div>
<ul>
<li ng-repeat="listitem in list track by $index">
<button type="button" class="btn-u btn-brd btn-u-none" ng-click="edit(listitem, $index)" data-toggle="tab" href="#page2">
{{ listitem.name }}
</button>
</li>
</ul>
</div>
</div>
page2.html
<div ng-controller="appCtrl">
<div>
<ul>
<li ng-repeat="listitem in list track by $index">
<button type="button" class="btn-u btn-brd btn-u-none" ng-click="edit(listitem, $index)" data-toggle="tab" href="#page2">
{{ listitem.name }}
</button>
</li>
</ul>
</div>
</div>
的script.js
var app = angular.module('app', []);
app.controller('appCtrl', function($scope, $compile) {
var vm = this;
// List
$scope.list = [
{
'id': 1,
'name': 'afroza'
},
{
'id': 2,
'name': 'yasmin'
}
];
// edit function
$scope.edit = function(listItem, index) {
$scope.name = listItem.name;
//this one is very important
$compile(angular.element( document.querySelector('#name')))($scope);
};
});
答案 2 :(得分:0)
page1 and page2 and they are using same controller
- 他们没有使用相同的控制器。他们使用同一控制器的两个不同实例。
如果要使用相同的Controller实例,可以在父级上执行ng-controller="appCtrl as vm"
。否则,您可以使用rootScope
或service
答案 3 :(得分:0)
您应该添加两个组件,例如PageComponent和PageContainerComponent。 PageContainerComponent放在包含选项卡的母版页中。 PageComponent需要PageContainerComponent作为父级,并包含页面的逻辑。
然后,您可以简单地将任何想要共享的内容放在PageContainerComponent中,因为PageComponent可以访问它。如果您甚至可以在页面视图中将事物直接绑定到PageContainerComponent,那么您可以将PageContainerComponent作为PageComponent上的变量使用。
这样的事情:
angular.module('app').component('pageContainerComponent', {
controller: function() {
this.someProperty = 'yay';
},
template: '<div ng-transclude></div>'
});
angular.module('app').component('page1Component', {
controller: function() {
// This controller will now have a property tabsCtrl
// With the controller for pageContainerComponent
},
controllerAs: 'vm',
template: '<div>Page 1 content {{vm.tabsCtr.someProperty}}</div>',
require: {
tabsCtrl: '^myTabs'
},
});
用法应该是这样的
<page-container-component>
<div class="someTabClass">
<page1-component></page1-component>
</div>
</page-container-component>
这一切都来自我的头脑,所以这里或那里可能会有拼写错误,但我希望无论如何都有帮助。
修改强>
哦,差点忘了,你可以为page1Component和page2Component使用相同的控制器函数,使多个页面具有相同的控制器逻辑,但视图不同。我不是真的明白这一点,因为共享逻辑&#39;无论如何都应该在pageContainerComponent中。