2015-11-20 46 views
2

我有一個顯示項目列表的頁面。項目列表可以不斷變化,所以無論何時使用此頁面或刷新頁面,他都會看到新的項目列表。承諾退回後無法更新控制器的視圖

我目前使用Parse存儲我的項目,我將使用承諾與Parse API進行交互並獲取我的項目。下面是一個非常簡單的例子。

基本流程是當顯示index.html時,HomeCtrl.js將加載並調用ItemService.getItems()以獲取項目,將它們附加到$ scope.items,然後顯示對視圖的任何更改。 ItemService.getItems()是從Parse API提供的一個承諾。

app.js

var myApp = angular.module('myApp',[]); 
// Parse API keys 
Parse.initialize('MCNXFhdenmpSRN1DU8EJrG3YROXaX4bg0Q5IYwKp', 'XZfWd7J9xGSZQOizu0BoAtIUYtECdci4o6yR76YN'); 

的index.html

<html ng-app = 'myApp'> 
<script src="//www.parsecdn.com/js/parse-1.6.2.min.js"></script> 

<head> 
    <title> My Simple Example that doesn't work! </title> 
</head> 

<body layout="row"> 

    <div ng-controller = "HomeCtrl as ctrl"> 
     <div ng-repeat="item in ctrl.items"> 
      {{item.id}} 
     </div> 
    </div> 

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script> 
    <script src = "app.js"> </script> 
    <script src = "HomeCtrl.js"> </script> 
    <script src = "ItemService.js"> </script> 

</body> 
</html> 

ItemService.js

var myApp = angular.module('myApp'); 
myApp.service('ItemService', function(){ 

// gets all Items 
this.getItems = function() { 
    var Item = Parse.Object.extend("Item"); 
    var query = new Parse.Query(Item); 

    return query.find().then(function(items){ 
     return items; 
    }); 
    return this; 
    } 

}); 

HomeCtrl.js

var myApp = angular.module('myApp'); 
myApp.controller('HomeCtrl',[ 'ItemService', '$scope',function(ItemService, $scope){ 

    $scope.items = []; 

    ItemService.getItems() 
     .then(function(results){ 
      $scope.$apply(function() { 
       $scope.items = results; 
       console.log($scope.items); 
      }); 
     }); 

    console.log($scope.items); 
}]); 

$ scope.items在$ scope中做了更改。$ apply函數(我打印出來並可以看到一些項目),但是視圖沒有改變。當我在ItemService.getItems()後打印$ scope.items時,打印出一個空數組。

我是否在調用承諾後錯誤地更新$ scope.items,或者是否存在一些我不理解的概念?

任何幫助表示讚賞。


編輯

從456的回答,我看到,我在NG-重複他的回答作品犯了一個錯誤。不過,我想繼續使用controllerAs語法。我試圖在$ scope中更新this.items。$ apply函數但它不起作用 - this.items被修改,但是這個改變沒有在視圖中表示。我的修改是低於

的index.html

<div ng-controller = "HomeCtrl as ctrl"> 
    <div ng-repeat="item in ctrl.items"> 
     {{item.id}} 
    </div> 
</div> 

HomeCtrl.js

var myApp = angular.module('myApp'); 
myApp.controller('HomeCtrl',[ 'ItemService', '$scope',function(ItemService, $scope){ 

    this.items = []; 

    ItemService.getItems() 
     .then(function(results){ 
      $scope.$apply(function() { 
       this.items = results; 
       console.log(this.items); 
      }); 
     }); 
}]); 
+0

如果您在HTML中使用controllerAs語法,則不需要在控制器中使用$ scope。您可以在控制器中的此屬性上將這些元素添加到此變量中。 –

+0

@MahendraSingh我必須在控制器中使用$ scope來使用$ apply來更新視圖。有沒有辦法可以繼續使用'this'並獲得$ apply的相同影響? – Rohan

+0

當然你可以使用$ scope.apply,但是你的物品清單不需要在作用域上。 –

回答

1

ü應該叫它HTML像這個 -

<div ng-repeat="item in items"> 
+0

這是行不通的,但有沒有一種方法可以保持控制器的語法? – Rohan

+0

您可以將控件中的項目對象聲明爲this.items = []; ,而不是$ scope.items = []; – Disha

+0

請檢查我的編輯。我將這些項目聲明爲this.items並在$ scope。$ apply中進行修改,但視圖沒有更改。我做錯什麼了嗎? – Rohan

2

你所得到的錯誤由於當控件進入你的函數時,這個'this'將指向窗口對象。

ItemService.getItems() 
    .then(function(results){ 
     //Here 'this' will point to window 
     //window.items is undefined 
    }); 

因此錯誤。

你可以用很多方式解決這個問題,其中之一是使用另一個對象來指出這一點。

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

myApp.controller('HomeCtrl',[ 'ItemService', '$scope',function(ItemService, $scope){ 

var that = this; 
that.items = []; 

ItemService.getItems() 
    .then(function(results){ 
      that.items = results; 
    }); 
}]); 

試試這個,如果它適合你。