0

angular $scope を正しく使用する方法に頭を悩ませようとしています。私のアプリは、メイン ページの読み込み時にサーバーから受信した json データの URL リンクに基づいてビューを更新します。

ボタンをクリックすると、コントローラは次のデータ ファイルを取得しますが、このデータをスコープ変数に挿入してビューを更新することができません。ネットワークはデータを正常に送信するので、私のサービスは機能しています。

$scope で $resource の約束を解決し、アプリの初期化後にデータを取得するときにビューを更新する方法がわかりません。この問題について何か助けていただければ幸いです。

私の ListController :

//View updates correctly when promise resolves
$scope.data = DataElements.get({}); 

$scope.nextPage = function (){ //Called when clicking 'next' button
var url = $scope.data.pager.nextPage; 

var pageNumber = url.split("page=").pop(); //Ugly but it is temporary, I promise..

//View doesnt update
DataElements.get({'page': pageNumber}, function(data){ 
    $scope.data = data; 
});

//Error: Digest already in progress
DataElements.get({'page': pageNumber }, function(data){ 
    $scope.$apply(function(){
      $scope.data = data; 
    });
});

//View doesnt update
$scope.data = DataElements.get({'page': pageNumber)};  

};

サービス :

services.factory('DataElements', ['$rootScope','$resource', function($rootScope, $resource){
    return $resource($rootScope.baseUrl+'api/:endPointAdr.jsonp', 
        {'endPointAdr': 'dataElements', 'page': '@page'}, 
        { get : {'method' : 'JSONP', 'params' : {'callback' : 'JSON_CALLBACK'}}     
    });
}]);

意見 :

<section>
  <div>
    <h1>Search</h1>
    <input type="text" placeholder="Type something" autofocus>
    <input type="button" name="filter" value="Filter">
    <input type="button" name="clear" value="Clear">
    <div class="btn-toolbar" role="toolbar" aria-label="...">
      <a class="btn btn-default" href="#" aria-label="Previous Page">
        <span class="glyphicon glyphicon-chevron-left"></span>
      </a>
      <a class="btn btn-default" href="#" ng-click="nextPage()" aria-label="Next Page">
        <span class="glyphicon glyphicon-chevron-right"></span>
      </a>
    </div>
  </div>
  <div ng-controller="ListController">
    <ul class="" ng-show="data">
      <li class="" ng-repeat="element in data.dataElements ">
        <a href="#">
          <div class="info">
            <h2>{{element.name}}</h2>
          </div>
        </a>
      </li>
    </ul>
  </div>
</section>

サーバーの応答:

DataElements.get({}) == >
angular.callbacks._1({"pager": {"page":1,"pageCount":15,"total":706,"nextPage":"http// ...});(*)

DataElements.get({'page': 2})  == > 
angular.callbacks._2({"pager": {"page":2,"pageCount":15,"total":706,"nextPage":"http:// ...});(*)

(*) $resource は jsonp を取り除き、json のみを返します。

アップデート :

関数スコープでのみ割り当てる$scope.dataと、完全に機能します。ディレクティブがこの関数を でラップしnextPageていることは知っています。したがって、apply を明示的に呼び出すとエラーが発生することは理にかなっています。ng-click$scope.apply()

解決 :

<div ng-controller="ListController">$scope が異なる複製コントローラーを作成しました。それを削除すると、問題が修正されました。詳細については、私の回答を参照してください。

4

3 に答える 3

1

DataElements.getpromise オブジェクトを返す場合は、thenメソッドを呼び出す必要があります。

DataElements.get({'page': pageNumber}).then(function(data) {
   $scope.data = data;
})

$promiseまたは $resource を使用している場合、通常はプロパティを持つオブジェクトを返します。

DataElements.get({'page': pageNumber}).$promise.then(function(data) {
   $scope.data = data;
})
于 2014-11-16T12:12:05.340 に答える
0

おっしゃったように、データ$scopeは更新されていますが、変更はビューに反映されていません。何かが双方向バインディングを壊しています。

F12コンソール ( Chrome) でどのようなエラーが表示されるかを確認します。

このコード ブロックを削除します。

//Error: Digest already in progress
DataElements.get({'page': pageNumber }, function(data){ 
    $scope.$apply(function(){
      $scope.data = data; 
    });
});

//View doesnt update
$scope.data = DataElements.get({'page': pageNumber)};  

明示的に使用することは避けてください$apply。めったに良い考えではありません。

編集:

ListControllerOP は混乱を避けるために へのバインディングを削除することで問題を解決しましたが$scope、現在の HTML コードは少し奇妙に見えます。最適な解決策は、 にバインドするディレクティブを作成ListControllerし、ビューでこのディレクティブを再利用することです。そうすれば、OPは$scope将来そのような問題を回避します。

于 2014-11-16T13:14:03.530 に答える