2016-11-16 25 views
0

我在JS中有一些技巧,而且我幾乎是新手Angular。我有一個關於$ watch如何工作的問題。任務 - 以正確的方式在指令和控制器之間共享數據。據我所知,最佳做法是使用服務共享數據。所以,我有:

指令

angular.module('app.directives').directive('ffDomains', function(sharedData) { 
... 
    $scope.navigateTo = function(domain, event) { 
     $scope.activeDomain = domain; 
     sharedData.setDomain(domain); 
    }; 
... 
} 

工廠

angular.module("app.factories").factory('sharedData', function() { 
    var domain = null; 

    return { 
     setDomain: setDomain, 
     getDomain: getDomain 
    }; 

    function setDomain(_domain) { 
     domain = _domain; 
    } 

    function getDomain() { 
     return domain; 
    } 

}); 

和控制器

angular.module('app.controllers').controller('mainController', ['$scope', 'sharedData', function ($scope, sharedData) { 

    $scope.currentDomain = {}; 
    $scope.$watch(function() {return sharedData.getDomain()}, function() { 

     if (sharedData.getDomain()) { 
      $scope.currentDomain = sharedData.getDomain(); 
     } else { 
      $scope.currentDomain.domain = 'All domains'; 
     } 
    }); 

}]); 

的問題是爲什麼要使用函數(){返回sharedData.getDomain( )}而不是sharedData.getDomain ()在看?最後一個是域名變量在我的服務中的鏈接。爲什麼它是不夠的呢?

非常感謝您的幫助。我感謝你的時間。

+0

你可以試試看下面的$ scope。$ watch(sharedData.getDomain,...'。 –

回答

0

關於你的問題:

的問題是,爲什麼我要使用的功能()在手錶{返回sharedData.getDomain ()},而不是sharedData.getDomain()? 最後一個是我的服務中的域變量的鏈接。爲什麼它不是 就足夠了嗎?

正如official documentation描述:

到$每次調用消化(),並應 返回將要觀看的價值watchExpression被調用。 (watchExpression應當以相同的輸入 執行多次,因爲它可以通過$消化物(被執行多次不 改變它的值)。即, watchExpression應該是冪等的。)

watchExpression可以是:

  • 字符串
  • 功能

的 「弦」是一個有效的AngulaJS expression。如文檔中所述:

角表達式是像下面 差異JavaScript表達式:

  • 上下文:JavaScript表達式是針對全局窗口進行評價。在Angular中,表達式是針對scope對象進行評估的。

...

所以,如果你在watchExpression指定一個 「串」,AngularJS會評估對範圍的表達。

如果您通過function作爲watchExpression,該函數將返回要監視的值。每當觀察值無法在範圍內輕鬆檢索時使用「函數」(否則可以使用「字符串」表達式而不是「函數」一個)。

在您的例子中,watchExpression是:

function() {return sharedData.getDomain()} 

sharedData服務不在範圍內(例如,$scope.sharedData = {...})中定義的變量,但定義別處一個角度的服務。出於這個原因,你必須使用函數()作爲watchExpression,否則Angular不能觀察域的變化。

+0

謝謝!我有一個想法,原因是我試圖觀察超出當前範圍的服務。我在文檔中錯過了這一點。而我錯過了我應該在這種情況下使用回調。 –

+0

不客氣。如果您發現我的回答或任何其他答案可解決您的疑問,請將其標記爲已接受:) – Andrea

0

在這個特定情況下,您指的是工廠,因此是當前範圍之外的變量。

當您將一個變量傳遞給觀察者時,angular將在當前範圍內評估字符串,並且顯然它不存在。

var domain sharedData.getDomain(); 
$scope.$watch('domain', function(newVal, oldVal) { 
//domain doesn't exist in the current scope 

}); 

每次你想觀看你必須提供一個回調作爲將在dygest週期中被觸發參數的當前範圍之外的東西。

$scope.$watch(function(){ 
    return sharedData.getDomain() 
}, function(newVal, oldVal) { 

}); 
+0

謝謝!我知道它是一個小的offtopic,但是如何啓動dycine循環?我閱讀了一些文檔,但不明白100%,我知道這不是一個計時器) 所以它是正確的,如果我說在這種情況下角度監視每個變量(包括我的工廠),如果工廠變量變化 - 它看起來$ watch(不僅手動配置)所有與此工廠範圍相關的變量? –

+0

摘要循環是一種由角的核心定期執行的循環(例如每x毫秒),這觸發了應用程序的所有觀察者。例如ng-click指令(和所有的角度指令)自己調用$ scope.apply()將變量添加到dygest循環中。這甚至對你的作用域中的所有變量都有效,相反,如果你執行代碼「outside angular」,例如原生javascript(假設setTimeout(..)),則必須將內容包裝在$ scope.apply( ),那觸發器本身就是dycine週期,否則你的模型將不會被更新。 – Karim

+0

好的,明白了。非常感謝!最後一個問題:我的方法是否正確地在控制器和指令之間共享數據,還是存在更合適的方法? –

相關問題