2014-10-03 66 views
1

我在AngularJS的數據綁定中遇到了一些麻煩。 總之,我試圖將我的工廠變量鏈接到我的視圖($ scope)。 工廠(在我的完整實現中)偵聽特定的廣播並更新變量,視圖應該反映這種變化,但事實並非如此。Angularjs在工廠和視圖之間進行數據綁定

我設法從大部分其他代碼中分離出這個問題。控制器調用的函數(setTrue)只是一些難度較大的後端操作的佔位符。

運行代碼時,我希望在視圖中看到「true」。我不知道爲什麼這個觀點仍然是「假」?

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script> 
<body ng-app="app"> 
    <div ng-controller="Fact"> 
     value: {{model}}<br/> 
    </div> 

    <script type="text/javascript"> 
     var app = angular.module("app", []); 

     app.controller('Fact', ['$scope','Fact', function ($scope, Fact) { 
      $scope.model = Fact.data; 
      Fact.setTrue(); 
     }]); 

     app.factory("Fact", function() { 
      var Fact = {}; 
      Fact.data = false; 

      Fact.setTrue = function() { 
       Fact.data = true; 
      }; 

      return Fact; 
     }); 
    </script> 
</body> 

Plunker:http://plnkr.co/edit/IIq2H4gW1DBoe5zVPx0g

可有人告訴我,我做錯了什麼?

編輯:

當我改變了上面的代碼有

$scope.model = Fact; 

value: {{model.data}} 

這突然的作品...但我不喜歡把我的整個工廠都在我的範圍內。

+2

布爾值通過值傳遞,而不是通過引用 – JoseM 2014-10-03 14:10:48

+1

爲什麼您反對將工廠對象放在範圍內?這是做到這一點的正確方法,當你創建一個工廠它是一個單身對象,並且它應該被用來設置範圍值 – 2014-10-03 14:40:16

+0

@JaredReeves如果我只是把工廠放在$ scope中,那麼我真的不會看到有控制器的一點? – user3319803 2014-10-03 14:45:29

回答

0

調用正如你已經知道下面的代碼將正常工作。正如你所看到的,我將返回的單例賦值給一個範圍值。從這我可以瘦調用這個新的作用域對象的工廠返回的所有方法。

angular.module("app", []) 
 
    .controller('appCtrl', ['$scope', 'Fact', 
 
    function($scope, Fact) { 
 
     $scope.model = Fact; 
 
     $scope.model.setTrue(); 
 
    } 
 
    ]).factory("Fact", function() { 
 
    var Fact = {}; 
 
    Fact.data = false; 
 

 
    Fact.setTrue = function() { 
 
     Fact.data = true; 
 
    }; 
 

 
    return Fact; 
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script> 
 

 
<div ng-app="app"> 
 
    <div ng-controller="appCtrl"> 
 
    value: {{model.data}} 
 
    <br/> 
 
    </div> 
 
</div>

在你的情況,我認爲這將是完成你想要什麼樣的正確方法。我假設你可以考慮其他工廠可能有大量關聯的場景,並且可以訪問控制器中的整個對象。

在下面的代碼片段中,我將布爾值封裝在一個對象中,並像您一樣分配給作用域,但現在任何更改都將綁定到$ scope.model對象。

angular.module("app", []) 
 
    .controller('appCtrl', ['$scope', 'Fact', 
 
    function($scope, Fact) { 
 
     $scope.model = Fact.data 
 
     Fact.setTrue(); 
 
     //$scope.model.setTrue(); 
 
    } 
 
    ]).factory("Fact", function() { 
 
    var Fact = {}; 
 
    Fact.data = {"value":false}; 
 

 
    Fact.setTrue = function() { 
 
     Fact.data.value = true; 
 
    }; 
 

 
    return Fact; 
 
    });
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script> 
 
<div ng-app="app"> 
 
    <div ng-controller="appCtrl"> 
 
    value: {{model.value}} 
 
    <br/> 
 
    </div> 
 
</div>

但是,如果你不想做這樣的,只是想將數據值分配給範圍,需要改變的事實工廠指派的值之前範圍或將其包裝在一個對象中,然後該對象將傳遞引用而不是值。應該注意的是,在你的代碼中,你爲$ scope.model指定了一個布爾值,但是它並沒有綁定到Fact.data,因此對Fact的任何改變都不會影響模型對象。

+0

你的第二種方法就是我最終使用的方法。所以把它包裹在一個物體中。你認爲某種方法比另一種更好嗎? – user3319803 2014-10-03 15:35:32

+0

這真的取決於實施。我更喜歡第二種方法,因爲它可以讓你在工廠調用函數而不是新對象,如果你的數據是一個更復雜的對象(比如用戶對象),那麼你尤其如此,那麼你將一些屬性綁定到範圍。 – 2014-10-03 15:39:37

+0

請注意,你會遇到其他情況,你需要將一個布爾值包裝在一個對象中才能綁定到工作中,我可以想到的一種情況是ng-if。 – 2014-10-03 15:41:03

0

我對你使用工廠的方式感到非常驚訝。

你是不是應該做更多的東西一樣:

(function() { 
angular.module("services") 
.factory("dataService", function ($http) { 

    var data = ""; 

    var getData = function() { 
    return data; 
    } 

    var setData = function(newData) { 
    data = newData; 
    } 

    return { 
    getData: getData, 
    setData: setData 
    }; 

}); 

})();

,然後你只需要在你的控制器

app.controller('Ctrl', ['$scope','dataService', function ($scope, dataService) { 
     $scope.model.data = dataService.getData(); 
     dataService.setData("something"); 
    }]); 
+0

你正在使用的符號也是可能的。我只是在學習一些教程,並在那裏展示了這種寫作方式。 但是(據我所知)你不應該在Angular中使用getters和setter,只需使用自動數據綁定。 – user3319803 2014-10-03 14:59:54

+0

@sam你確定這有效嗎?因爲'data = newData;'會破壞數據綁定,並且控制器的作用域不會更新。 我認爲這隻適用於'angular.extend(data,newData);' – ProblemsOfSumit 2015-11-17 16:26:27