2015-11-02 97 views
1

更新其他控制器範圍我是AngularJS一個新手,所以也許我在看這個錯誤的方式。如果是這樣,請指向正確的方向。使用AngularJS服務從其他模塊

基本上我想更新駐留在另一個模塊中的另一控制器一些DOM元素。 我試圖通過服務發送數據,但它似乎沒有在目標範圍上更新。

var mainModule = angular.module('main', []); 
var appModule = angular.module('app', ['main']); 


appModule.controller("appCtrl", function ($scope, $routeParams, mainService) { 

    $scope.mainService = mainService; 

    var initialize = function() { 
     $scope.mainService.currentID = $routeParams.productId; 
    } 

    initialize(); 
}); 


mainModule.factory('mainService', function() { 
    var mainService = { currentID: 0 }; 
    return mainService 
}); 

mainModule.controller('mainCtrl', ['$scope', 'mainService', function ($scope, mainService) { 

    $scope.mainService = mainService; 
    $scope.function1Url = "function1/" + $scope.mainService.currentID; 
    $scope.function2Url = "function2/" + $scope.mainService.currentID; 
    //CurrentID is always 0!! 
}]); 

我預計,在appCtrl調用initialize()功能時,它會看到currentID PARAM其中也使用mainCtrl服務。

+0

您忘了注入$ routeParams –

回答

2

對於使用服務更新控制器,我強烈建議你使用$rootScope.$broadcast$rootScope.$on。這裏是鏈接的,你如何能做到這一點的例子,一個博客:

$rootScope.$broadcast('myCustomEvent', { 
    someProp: 'Sending you an Object!' // send whatever you want 
}); 

// listen for the event in the relevant $scope 
$rootScope.$on('myCustomEvent', function (event, data) { 
    console.log(data); // 'Data to send' 
}); 

http://toddmotto.com/all-about-angulars-emit-broadcast-on-publish-subscribing/

這是你的工作的解決方案:

var mainModule = angular.module('main', []); 
var productModule = angular.module('product', ['main']); 

productModule.service('mainService', ['$rootScope', '$timeout', function ($rootScope, $timeout) { 
    this.method1 = function() { 
     alert('broadcast'); 
      $rootScope.$broadcast('myCustomEvent', { 
       newValue: 'This is an updated value!' 
      }); 
    } 
}]); 

productModule.controller('mainCtrl', ['$scope', '$rootScope', function ($scope, $rootScope){ 

    $scope.myValue = 'Initial value'; 

    $rootScope.$on('myCustomEvent', function (event, data) { 
     $scope.myValue = data.newValue; 
     alert('received broadcast'); 
    }); 

}]); 

productModule.controller("productCtrl", function ($scope, mainService) { 

    $scope.mainService = mainService; 
    $scope.clickMe = 'Click to send broadcast'; 

    $scope.callService = function() { 
     $scope.clickMe = 'Broadcast send!'; 
     $scope.mainService.method1(); 
    } 


}); 

和HTML:

<body ng-app='main'> 
    <div ng-controller="mainCtrl"><b>My value:</b>{{myValue}}</div> 

    <div id="product" ng-controller="productCtrl"> 
     <button ng-click="callService()">{{clickMe}}</button> 
    </div> 

    <script type="text/javascript">angular.bootstrap(document.getElementById("product"), ['product']);</script> 
    </body> 
+0

請注意$ rootScope。$ broadcast將發送給所有範圍(性能)。使用$ scope。$發出,如果你需要通知的是你。或$ scope。$如果它是你的孩子,則廣播。 – Vince

+0

我試過$ rootScope。$廣播,但它似乎從來沒有收到。我已經成立了一名Plunker來展示這個問題。 [Plunker鏈接](http://plnkr.co/edit/GjTxszyE5iVDy1DN9V7H?p=preview) – Wesman80

+0

我得到它的工作 – uksz

0

你有幾個不同的方法來做到這一點。

我uksz同意,你應該使用的廣播/發射讓其他示波器知道的變化,讓他們去處理需要。

廣播轉到元素的所有子範圍

$scope.$broadcast("Message Name", "payload, this can be an object"); 

的Emit進入這個元素

$scope.$emit("message name", "payload, this can be an object"); 

另一種選擇是,你也可以要求其他控制器的所有父範圍

appModule.directive('myPane', function() { 
    return { 
    require: '^myTabs', 
    scope: {}, 
    link: function(scope, element, attrs, tabsCtrl) { 
     tabsCtrl.addPane(scope); 
    } 
    }; 
}); 

最後,你可以包括範圍的功能,所以你可以讓家長SCO pe知道發生了什麼

appModule.directive('myPane', function() { 
    return { 
    scope: { 
     doSomething: '&something' 
    }, 
    link: function(scope, element, attrs) { 
     $scope.doSomething(test); 
    } 
    }; 
});