2013-09-28 428 views
1

我有一個指令,範圍變量依賴於其他範圍變量。我期望如果等式右邊的範圍變量改變了它會更新左邊,但這似乎並沒有發生。Angular JS範圍變量依賴於另一個範圍變量,不會更新

在下面的例子中,當運行selectProduct()時,它應該更新產品信息,包括產品標題,但它不起作用,除非我直接更新scope.title,就像函數底部的註釋行一樣。

controller:function($scope){ 
     $scope.products = $scope.productGroup.products; 

     $scope.selected_product = $scope.productGroup.products[$scope.productGroup.selected_product]; 
     $scope.title = _.isEmpty($scope.selected_product) ? $scope.productGroup.title : $scope.selected_product.title; 
     $scope.excerpt = _.isEmpty($scope.selected_product) ? $scope.productGroup.excerpt : $scope.selected_product.excerpt; 
     $scope.description = _.isEmpty($scope.selected_product) ? $scope.productGroup.description : $scope.selected_product.description; 

     $scope.selectProduct = function(){ 
      $scope.selected_product = $scope.productGroup.products[1]; 
      console.log($scope.selected_product); 
      //$scope.title = $scope.selected_product.title; 
     } 
    }, 

回答

1

在模板中只是綁定到{{ selected_product.title }},而不是設置$scope.title = $scope.selected_product.title,並結合{{ title }}

根據經驗,不要誤用$scope作爲您的型號。甚至不是你的ViewModel。 JavaScript的原型繼承和可變參考系統使得Angular不會真正遵循傳統的MVVM模式,其中$scope將是您的ViewModel。

沒有你的問題的工作示例,我想在黑暗中嘗試一下,並建議你將代碼重構成類似的東西。

controller:function($scope){ 
    $scope.products = $scope.productGroup.products; 
    $scope.selected_product = $scope.products[$scope.productGroup.selected_product] || { 
     title: $scope.productGroup.title, 
     excerpt: $scope.productGroup.excerpt, 
     description: $scope.productGroup.description 
    }; 

    $scope.selectProduct = function(){ 
     $scope.selected_product = $scope.productGroup.products[1]; 
    } 
}, 

請務必閱讀這一塊更多的背景信息:

What are the nuances of scope prototypal/prototypical inheritance in AngularJS?

你的問題其實並不完全似乎與原型繼承的東西,但還是請務必閱讀和明白它。據我看來,在你的代碼中,真正的問題是你的設置$scope.title一次,然後期望它自動改變爲$scope.selected_product,但爲什麼要這樣呢?這兩者之間沒有神奇的聯繫。但是,如果您將代碼重構爲我提供的代碼,則不僅可以使綁定起作用,而且還可以減少重複的_.isEmpty()支票(我懷疑您實際上首先需要這些支票;-))

+0

謝謝。但是如果我有一些外部函數將'$ scope.productGroup.selected_product'從0改爲1,現在我想讓scope.selected_product相應地更新,同時顯式地設置$ scope.selected_product。角度不知道一個範圍對象依賴於另一個範圍對象屬性嗎?在我看來,由於select_product的值取決於productGroup.selected_product屬性,所以更改select_product屬性也應該更新摘要循環中的selected_product。 – michael

+0

您可以創建一個類似於'$ scope。$ watch('productGroup.selected_product',function(){$ scope.selectedProduct = ...}'的手動手錶。但是說實話,爲什麼要將這個任務卸載到Angular?I如果您的productGroup公開了一個方法'setSelectedProduct(index)',然後在內部將'productGroup.selected_product'設置爲產品的實例(而不是索引),那麼它會更好的API設計,然後在您的模板中綁定到'productGroup.selectedProduct'。這對你有意義麼? – Christoph

+0

是的,我對將selectedProduct函數放在哪裏感到困惑,這就是我想要做的事情,我的productGroup只是來自服務的json數據。將它變成一個更大的對象,這樣我就可以添加一個API到它的正確方法(僅供參考,我在同一個屏幕上有多個產品組,所以我想不出一種方法來正確實施這個工廠)。 – michael