Javascript AngularJS控制器和rootScope的多种用途

Javascript AngularJS控制器和rootScope的多种用途,javascript,data-binding,controller,angularjs,Javascript,Data Binding,Controller,Angularjs,我想在两个单独的HTML元素上使用控制器,并在编辑一个列表时使用$rootScope使两个列表保持同步: HTML <ul class="nav" ng-controller="Menu"> <li ng-repeat="item in menu"> <a href="{{item.href}}">{{item.title}}</a> </li> </ul> <div ng-contr

我想在两个单独的HTML元素上使用控制器,并在编辑一个列表时使用$rootScope使两个列表保持同步:

HTML

<ul class="nav" ng-controller="Menu">
    <li ng-repeat="item in menu">
        <a href="{{item.href}}">{{item.title}}</a>
    </li>
</ul>

<div ng-controller="Menu">
    <input type="text" id="newItem" value="" />
    <input type="submit" ng-click="addItem()" />
    <ul class="nav" ng-controller="Menu">
        <li ng-repeat="item in menu">
            <a href="{{item.href}}">{{item.title}}</a>
        </li>
    </ul>    
</div>
加载页面时,
UL
DIV
都会显示数据库中的正确内容,但当我使用
addNewItem()
方法时,只有
DIV
会得到更新

有没有更好的方法来组织我的逻辑,或者我可以做些什么来确保
UL
中的
$scope.menu
同时得到更新

下面是一个类似的示例:

编辑:

这是最新版本。它在两个控制器中工作

主要思想是使用服务和广播将数据与指令同步

app.service('syncSRV', function ($rootScope) {
    "use strict";
    this.sync = function (data) {
        this.syncData = data;
        $rootScope.$broadcast('updated');
    };
});
app.controller('MainCtrl1', ['$scope', function ($scope) {
    }])
    .controller('MainCtrl2', ['$scope', function ($scope) {
    }]);
app.directive('sync',function (syncSRV) {
    "use strict";
    return {
        template: '<div><input ng-model="syncdata" type="text" /></div> ',
        controller: function ($scope, $element, $attrs) {
            $scope.$watch('syncdata', function (newVal, oldVal, $scope) {
                syncSRV.sync(newVal);
            }, true);
        }
    };
}).directive('dataview', function (syncSRV) {
    "use strict";
    return {
        template: '<div>Sync data : {{data}}</div> ',
        controller: function ($scope, $element, $attrs) {
            $scope.$on('updated', function () {
                $scope.data = syncSRV.syncData;
            });
        }
    };
});


<div ng-controller="MainCtrl1">
    <fieldset>
        <legend> Controller 1</legend>
        <div dataview></div>
        <div sync></div>
    </fieldset>
</div>
<div ng-controller="MainCtrl2">
    <fieldset>
        <legend> Controller 2</legend>
        <div dataview></div>
        <div sync></div>
    </fieldset>
</div>
app.service('syncSRV',函数($rootScope){
“严格使用”;
this.sync=函数(数据){
this.syncData=数据;
$rootScope.$broadcast('updated');
};
});
应用程序控制器('MainCtrl1',['$scope',函数($scope){
}])
.controller('maintrl2',['$scope',函数($scope){
}]);
应用指令('sync',函数(syncSRV){
“严格使用”;
返回{
模板:“”,
控制器:函数($scope、$element、$attrs){
$scope.$watch('syncdata',函数(newVal,oldVal,$scope){
syncSRV.sync(newVal);
},对);
}
};
}).directive('dataview',函数(syncSRV){
“严格使用”;
返回{
模板:“同步数据:{{data}}”,
控制器:函数($scope、$element、$attrs){
$scope.$on('updated',function(){
$scope.data=syncSRV.syncData;
});
}
};
});
控制器1
控制器2
下面是我为这个案子所做的

我将为创建一个指令

<ul class="nav" ng-controller="Menu">
        <li ng-repeat="item in menu">
            <a href="{{item.href}}">{{item.title}}</a>
        </li>
</ul> 
所以,一旦项目被更新,它将在两个指令中都被更新


我建议使用包含菜单及其方法的服务。服务将更新控制器引用的菜单

在此处查看正在工作的plunker:

以下是示例JavaScript代码:

angular
 .module( 'sampleApp', [] )
 .service( 'MenuService', [ '$rootScope', function( $rootScope ) {

   return {
      menu: [ 'item 1' ],
      add: function( item ) {
        this.menu.push( item );
      } 
   };

 }])
 .controller( 'ControllerA', [ 'MenuService', '$scope', function( MenuService, $scope ) {

   $scope.menu = MenuService.menu;

   $scope.addItem = function() {
    MenuService.add( $scope.newItem );  
   };

 }]);
以及示例Html页面:

<!DOCTYPE html>
<html>

  <head lang="en">
    <meta charset="utf-8">
    <title>Custom Plunker</title>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
    <script src="app.js"></script>
  </head>

  <body ng-app="sampleApp">

    <div ng-controller="ControllerA">
      <ul>
        <li ng-repeat="item in menu">{{item}}</li>
      </ul>
      <input type="text" ng-model="newItem" /><input type="submit" ng-click="addItem()" />
    </div>

    <div ng-controller="ControllerA">
      <ul>
        <li ng-repeat="item in menu">{{item}}</li>
      </ul>
    </div>

  </body>

</html>

海关抢劫犯
  • {{item}
  • {{item}

我只想更新并简化所选答案。似乎可以通过删除这一行来减少这一点:
$rootScope.$broadcast('MenuService.update',this.menu')

这一块:

$scope.$on( 'MenuService.update', function( event, menu ) {
 $scope.menu = menu;
});
原因是,我们已经在使用一个服务,它基本上绑定了两个相同的控制器,因此不需要使用$rootScope.$broadcast并添加一个可观察的

在这里工作:


您只需要链接服务,当我重构代码时,我可以将其减少到13行而不是22行。

您的示例只有一个控制器,这是否仍然可以跨两个不同的控制器工作?e、 g.:。我受限于如何修改我的页面HTMLYou可以在服务中保留菜单以及更新菜单本身的方法,并让服务通过$rootScope.$broadcast广播更新后的菜单。控制器已使用$scope.$on监听事件,并通过$scope.menu=…更新菜单的区域设置引用。我更新了我的答案,以防您想知道如何在指令中执行此操作。此答案还包括一个非常有用的视频:就是这些内容,在您发布该评论后我正在查看此内容,谢谢!调用
$scope.menu
时,即使没有
$rootScope.$broadcast
$scope.$on
功能,也不会自动更新
$scope.menu
?由于
$scope.menu
直接指向
MenuService.menu
,因此它不是它的副本。@KajMagnus谢谢,我更新了答案和相关的插件。因此,将同一个控制器附加到多个视图元素是一种非常糟糕的做法吗?或者在开发过程中是否有过这样的解决方案是可以接受的?我在webdev工具控制台中没有看到错误,当运行webapp时,它有如此肮脏的黑客(?)。
$scope.$on( 'MenuService.update', function( event, menu ) {
 $scope.menu = menu;
});