2014-06-13 102 views
1

我有一個問題綁定與角度的數據。
我的模型:雙向綁定不是woking

<div id="ng-app-MyApp"> 
    <ng-view></ng-view> 
</div> 

控制器:

angular.module("MyApp.controllers", []). 
controller("myController", function($scope, service) { 
    $scope.someprop = "12"; 
    $scope.nameFilter = "text here"; 
    $scope.val = ""; 

    setTimeout(function() { 
     $scope.val = "321"; 
    }, 1000); 

    $.when(service.getItems()).done(function (items) { 
     console.log(items.length); 
     $scope.someprop = "hello"; 
    }); 
}); 

的index.html:

<div> 
    <input type="text" ng-model="nameFilter" /> 
    <div>{{nameFilter}}</div> 
    <table> 
     <tr> 
      <td>{{someprop}}</td> 
      <td>{{val}}</td> 
     </tr> 
    </table> 
</div> 

我使用手動結合(angular.bootstrap($("#ng-app-MyApp")[0], ["MyApp"]);)。 service.getItems()返回jQuery延遲對象。 當頁面加載時,我預計someprop的值變成「hello」,而val將等於「321」。但實際上並沒有發生。當我開始在文本框中輸入內容時,執行了數據綁定,我可以在用戶界面上看到someprop =「hello」和val =「321」。

我不明白,爲什麼這個屬性不會自動更新,但只有當我開始輸入文本框?

回答

1

添加$scope.$apply()

$.when(service.getItems()).done(function (items) { 
     console.log(items.length); 
     $scope.someprop = "hello"; 
     $scope.$apply(); 
    }); 

你需要調用它,因爲你正在處理角度的框架(jQuery的),並刷新依賴的事件之外的回調不會引起人們的關注。

$apply是功能「重載/刷新」綁定


如果可能的話,我建議你嘗試避免你的角碼的jQuery

如果service.getItems()是一個簡單的Ajax請求,使用$http角度的服務,而不是jQuery和編輯您的自定義服務是這樣的:

服務:

... 
service.getItems = function() 
{ 
    return $http.get('<url>'); 
}; 
... 

控制器:

service.getItems() 
    .success(function(data) 
     { 
      console.log(items.length); 
      $scope.someprop = "hello"; 
     }); 

注意,使用純的角,你不需要添加$apply()

+0

能否請您解釋一下,爲什麼我需要調用'適用()'手動?在我看到的所有例子中都沒有應用方法。 – Kai

+0

'service.getItems()'是一些對象上的延遲封裝。它不打算用於Ajax請求。是否有可能使用角度來製作這種包裝?類似於'var def = angular.deferred(); ...' – Kai

+0

@Kai,https://docs.angularjs.org/api/ng/service/$q –

1

你錯過了$消化過程負責雙向數據angularjs綁定(雖然爲什麼你懶得使用jQuery的承諾,當你可以實現完全相同的純angularjs)

,以避免你可以做到這一點

$.when(service.getItems()).done(function (items) { 
    console.log(items.length); 
    $scope.apply(function(){ 
    $scope.someprop = "hello"; 
    }) 
}); 

$.when(service.getItems()).done(function (items) { 
    console.log(items.length); 
    $timeout(function(){ 
    $scope.someprop = "hello"; 
    }) 
}); 

$.when(service.getItems()).done(function (items) { 
    console.log(items.length); 
    $scope.someprop = "hello"; 
    $scope.$digest() 
}); 

雖然最後一個是有點棘手,如果應用程序是大,消化情況經常發生,可能會引發錯誤digest already in progress

0

兩個項目未設置,因爲他們已經錯過了摘要。你想使用數據綁定的一切都必須通過服務來完成。

要在這裏覆蓋這個就是你需要做的:

setTimeout(function() { 
    $scope.$apply(function() { 
     $scope.val = "321"; 
    }); 
}, 1000); 

$.when(service.getItems()).done(function (items) { 
    console.log(items.length); 
    $scope.$apply(function() { 
     $scope.someprop = "hello"; 
    }); 
});