Je veux utiliser un contrôleur sur 2 éléments HTML séparés et utiliser $ rootScope pour garder les 2 listes synchronisées lorsqu'une est éditée:
[~ # ~] 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();
}
Lorsque la page se charge, UL
et DIV
affichent le contenu correct de la base de données, mais lorsque j'utilise la méthode addNewItem()
uniquement la DIV
est mis à jour.
Existe-t-il une meilleure façon de structurer ma logique, ou puis-je faire quelque chose pour m'assurer que le $scope.menu
Dans le UL
est mis à jour en même temps?
Voici un exemple de quelque chose de similaire: http://plnkr.co/edit/2a55gq
Éditer:
Voici la version mise à jour plunker . cela fonctionne dans deux contrôleur.
L'idée principale est d'utiliser le service et la diffusion pour synchroniser les données avec la directive.
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>
Voici ce que je ferais pour ce cas.
Je vais créer une directive pour
<ul class="nav" ng-controller="Menu">
<li ng-repeat="item in menu">
<a href="{{item.href}}">{{item.title}}</a>
</li>
</ul>
donc une fois l'élément mis à jour, il sera mis à jour dans les deux directives.
Je veux juste mettre à jour et simplifier la réponse sélectionnée. Il semble que vous pouvez réduire cela en supprimant cette ligne: $rootScope.$broadcast( 'MenuService.update', this.menu );
et ce morceau:
$scope.$on( 'MenuService.update', function( event, menu ) {
$scope.menu = menu;
});
La raison en est que nous utilisons déjà un service, et qui lie essentiellement les deux contrôleurs identiques, donc pas besoin d'utiliser $ rootScope. $ Broadcast et d'ajouter un observable.
Plunk de travail ici: http://plnkr.co/edit/1efEwU?p=preview
Il suffit de lier le service, quand j'ai refactorisé le code j'ai pu le réduire à 13 lignes au lieu de 22.