0

我正在創建一個繼承父控制器範圍的自定義指令。大多數情況下,我可以訪問我在控制器的「$ scope」中設置的指令的「範圍」對象,除了我在$ http.get中設置的屬性外。無論這些屬性來自API還是隻是從字面上定義都無關緊要。

對我來說很奇怪的是,如果我只記錄指令的「範圍」,我可以看到由$ http.get設置的屬性,但是如果我嘗試直接訪問它們,它們是未定義的。

我可以完美地訪問HTML視圖中的所有內容。

var myApp = angular.module('myApp'); 

myApp.controller('getData', function($scope, $http) { 
    var myData='myData.json'; 
    $scope.helloFromController = "Hello! This is the controller!"; 
    $scope.getTheData = function() { 
    $http.get(myData). 
     success(function(data, status) { 
     $scope.helloFromHttp = "Hello! This is the http!"; 
     }); 
    }; 
    $scope.getTheData(); 
}); 

myApp.directive('useData', function ($parse) { 
    var directiveObj = { 
    link: function (scope, element, attrs) { 
     console.log(scope); 
     // Returns the scope object that clearly includes the helloFromController and helloFromControllerHttp properties 
     console.log(scope.helloFromController); 
     // returns "Hello! This is the controller!" 
     console.log(scope.helloFromHttp) 
     // returns undefined 
    } 
    }; 
    return directiveObj; 
}); 

它看起來像是有$ $作用於$ http,我不明白。幫助表示讚賞。

+1

這不是關於$範圍,它只是事實,即ajax是異步的。 – dfsq

回答

0

您的指令共享控制器的相同範圍。在您的模板中找到指令時加載您的指令的鏈接函數。 $scope.helloFromController只是一個字符串。所以,你通過登錄控制檯看到了這一點。但是,在承諾解決$http後,將設置爲$scope.helloFromHttp。因此,在控制器中設置之​​前,您看不到該值爲console.log(scope.helloFromHttp)。您可以嘗試使用$ timeout來查看更改後的值scope.helloFromHttp

myApp.directive('useData', function ($parse, $timeout) { 
    var directiveObj = { 
    link: function (scope, element, attrs) { 
     // Returns the scope object that clearly includes the helloFromController and helloFromControllerHttp properties 
     console.log(scope); 

     // returns "Hello! This is the controller!" 
     console.log(scope.helloFromController); 

     // returns undefined 
     console.log(scope.helloFromHttp) 

     // set $timeout to trigger after 10 sec, you can reduce or increase the time 
     $timeout(function() { 
     console.log(scope.helloFromHttp); 
     }, 10000) 
    } 
    }; 
    return directiveObj; 
}); 

希望這會有所幫助。

+0

所以這個工作,但它似乎是不好的做法。有沒有更合理的方式將數據從$ http.get綁定到指令中? –

+0

正如我所說的,指令作用域中的'scope.helloFromHttp'將被更新爲指令作用域與控制器作用域相同。與綁定無關。但是,是的,如果你想在'scope.helloFromHttp'通過'$ http'更新後在指令鏈接函數中做某些事情,你可以在指令鏈接函數中'$ watch'變量。 – Saad

+0

這就是我剛纔所做的。我使用了$ watch「,並附帶了一個條件來查看scope.helloFromHttp是否存在,這很好,謝謝你的幫助! –

1

鏈接函數在調用異步http調用的回調之前執行。

示例代碼:http://jsfiddle.net/k54ubb9L/

<div ng-controller="MyCtrl" use-data> 
    Hello, {{ userData.username }}! 
</div> 


var myApp = angular.module('myApp', []); 

myApp.controller('MyCtrl', function($scope, $http) { 

    function getTheData() { 
    $http.get("http://jsonplaceholder.typicode.com/users/1"). 
    success(function(response, status) { 
     $scope.userData = response; 
    }); 
    }; 

    getTheData(); 
}); 

myApp.directive('useData', function($parse) { 
    return { 
    link: function(scope, element, attrs) { 
     scope.$watch("userData", function(newValue, oldValue) { 
     console.log(newValue, oldValue); 
     }); 
    }, 
    restrict: "A" 
    }; 
}); 
0

其實你的代碼工作沒有任何改變的罰款;問題在於您在控制檯中顯示它,但如果以HTML格式顯示它,則會按預期進行刷新。這裏的例子:http://plnkr.co/edit/WrqO7FeF5d5JdVas9jiL?p=preview

directive('useData', function($parse) { 
    return { 
    template: "From directive: {{helloFromHttp}}", 
    link: function(scope, element, attrs) { 

     console.log(scope); 
     // Returns the scope object that clearly includes the helloFromController and helloFromControllerHttp properties 
     console.log(scope.helloFromController); 
     // returns "Hello! This is the controller!" 
     console.log(scope.helloFromHttp); 
     // returns undefined 
    } 
    }; 
}); 
相關問題