19

2 つの分離された HTML 要素でコントローラーを使用し、$rootScope を使用して、編集時に 2 つのリストの同期を維持したいと考えています。

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>

JS

angular.module('menuApp', ['menuServices']).
    run(function($rootScope){
        $rootScope.menu = [];
    });

angular.module('menuServices', ['ngResource']).
    factory('MenuData', function ($resource) {
        return $resource(
            '/tool/menu.cfc', 
            {
                returnFormat: 'json'
            },
            {
                getMenu: {
                    method: 'GET',
                    params: {method: 'getMenu'}
                },
                addItem: {
                    method: 'GET',
                    params: {method: 'addItem'}
                }
            }
        );
    });

function Menu($scope, MenuData) {

    // attempt to add new item
    $scope.addNewItem = function(){
        var thisItem = $('#newItem').val();

        MenuData.addItem({item: thisItem},function(data){
            $scope.updateMenu();
        });
    }   

    $scope.updateMenu = function() {
        MenuData.getMenu({},function(data){
            $scope.menu = data.MENU;
        });         
    }

    // get menu data
    $scope.updateMenu();
}

ページが読み込まれると、ULと の両方DIVがデータベースから正しいコンテンツを表示しますが、addNewItem()メソッドを使用すると のみDIVが更新されます。

ロジックを構築するためのより良い方法はありますか、または が同時に更新される$scope.menuようにするために何かできることはありますか?UL

似たような例を次に示します: http://plnkr.co/edit/2a55gq

4

3 に答える 3

5

編集:

これが更新されたバージョンのプランカーです。2つのコントローラーで動作します。

主なアイデアは、サービスとブロードキャストを使用してデータをディレクティブと同期することです。

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>

これが私がこの場合に何をするかです。

のディレクティブを作成します

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

したがって、アイテムが更新されると、両方のディレクティブで更新されます。

小さな例

于 2012-11-01T15:53:07.250 に答える
1

選択した回答を更新して単純化したいだけです。この行を削除することでこれを減らすことができるようです: $rootScope.$broadcast( 'MenuService.update', this.menu );

そしてこのチャンク:

$scope.$on( 'MenuService.update', function( event, menu ) {
 $scope.menu = menu;
});

その理由は、既にサービスを使用しており、基本的に 2 つの同一のコントローラーをバインドしているため、$rootScope.$broadcast を使用してオブザーバブルを追加する必要がないからです。

ここで作業プランク: http://plnkr.co/edit/1efEwU?p=preview

サービスをリンクするだけで済みます。コードをリファクタリングすると、コードを 22 行から 13 行に減らすことができました。

于 2013-09-29T13:29:50.337 に答える