Проблема AngularJS в привязке данных ng-repeat

Сценарий

У меня есть повторитель, использующий ng-repeat, который привязывается к массиву вычисляемых значений динамического/времени выполнения. (т. е. мой массив содержит такие поля, как Brokerage: ($scope.BuyValue() + $scope.SellValue())* 0,5/100).

Проблема

Когда я изменяю значение в поле ввода, которое имеет ng-модель, поле Broker.Brokerage внутри повторителя не обновляется. Но я могу правильно обновить/привязать поля за пределами повторителя.

Код

<body ng-controller="BrokerController">
<div>
  <div>
    Buy Price   <input type="textbox" ng-model="BuyPrice"/><br/> 
    Sell Price  <input type="textbox" ng-model="SellPrice"/><br/> 
    Quantity    <input type="textbox" ng-model="Quantity"/><br/> 
    Buy Value   {{ BuyValue() }} <br/>
    Sell Value   {{ SellValue() }} <br/>
    Profit   {{ Profit() }} <br/><br/><br/>
    <h4>Brokers</h4>
    <div ng-repeat='Broker in Brokers'>
      Broker Name : <b>{{Broker.BrokerName}}</b>
      Brokerage Amount : <i>{{Broker.Brokerage}}</i>  ({{Broker.BrokerageDetail}})
      <br/>
    </div>
  </div>
</div>
  <script id="angularjs"  src="js/lib/angular/angular.js"></script>
  <script>
  var App = angular.module('ChooseYourBroker', []);

App.controller("BrokerController", ['$scope', function ($scope) {    
$scope.BuyPrice = 10;
$scope.SellPrice = 20;
$scope.Quantity = 100;
$scope.BuyValue = function(){ return ( $scope.BuyPrice * $scope.Quantity )};
$scope.SellValue = function(){ return ( $scope.SellPrice * $scope.Quantity )};
$scope.Profit = function(){ return ( $scope.SellValue() - $scope.BuyValue() )};
$scope.Brokers = [
    {
        BrokerName: 'Broker one', 
        BrokerageDetail :'0.5% value of Sell Value', 
        Brokerage: $scope.SellValue() * 0.5/100
    },
    {
        BrokerName: 'Broker two',  
        BrokerageDetail :'2% value of Sell Value', 
        Brokerage: $scope.SellValue() * 2/100
    },
    {
        BrokerName: 'Broker three', 
        BrokerageDetail :'1% value of Sell Value',  
        Brokerage: $scope.SellValue() * 1/100
    },
    {
        BrokerName: 'Broker Four', 
        BrokerageDetail :'0.5 % value of Buy Value and Sell Value',  
        Brokerage: ($scope.BuyValue() + $scope.SellValue())* 0.5/100
    }];
  }]);



  </script>   


person Sriram    schedule 11.06.2013    source источник
comment
Рабочий план для приведенного выше кода. -› http://plnkr.co/edit/pqqUxNvviDARTm3RBz7g Приветствуется любая помощь.   -  person Sriram    schedule 11.06.2013


Ответы (3)


Это связано с тем, что Brokerage вычисляется один раз при запуске. Поскольку вы не сделали из него геттерную функцию или не запустили наблюдатель, он не будет обновляться. У вас есть два варианта:

Вариант 1. Сделать геттер-функцию

JS:

{
    BrokerName: 'Broker Four', 
    BrokerageDetail :'0.5 % value of Buy Value and Sell Value',  
    GetBrokerage: function () { return ($scope.BuyValue() + $scope.SellValue())* 0.5/100;}
} 

HTML:

<span ng-bind="Broker.GetBrokerage()"></span>

Вариант 2. Смотреть BuyValue и SellValue и обновлять Brokers.

JS:

$scope.$watch("BuyValue()", function () { /*update all the brokers*/ });
$scope.$watch("SellValue()", function () { /*update all the brokers*/ });
person Umur Kontacı    schedule 14.06.2013

Вам нужно установить $watch на SellValue(), чтобы получать уведомления при каждом изменении возвращаемого значения:

$scope.$watch('SellValue()',function(newValue){
    for(var i=0;i<$scope.Brokers.length;i++){
        $scope.Brokers[i].Brokerage = ... * newValue; // Calculate the Brokerage
    }
});

Объяснение. Представление может связываться со значениями модели через область действия. Объект Brokers не является элементом представления и поэтому ни к чему не привязан. $watch необходим, когда модель хочет получать уведомления об изменениях в других частях модели. В противном случае ваше свойство Brokerage вычисляется только один раз во время начальной фазы запуска контроллера.

Вот скрипка, где я создал BrokerageRate для вычисления нового Брокерского вознаграждения при каждом изменении SellValue().

Broker Four потребуется немного больше работы, поскольку потребуется еще одно наблюдение за BuyValue(), поскольку это свойство Brokerage должно быть уведомлено об изменениях обоих значений.

скрипка

person Dan    schedule 14.06.2013

Таким образом, angularJS ng-model не обновляет примитивы. Если вы хотите, чтобы он автоматически обновлялся, было бы лучше сделать что-то вроде

$scope.share={};
$scope.share.BuyPrice = 10;
$scope.share.SellPrice = 20;
$scope.share.Quantity = 100;

и изменить

Buy Price   <input type="textbox" ng-model="BuyPrice"/><br/> 
Sell Price  <input type="textbox" ng-model="SellPrice"/><br/> 
Quantity    <input type="textbox" ng-model="Quantity"/><br/> 

to

Buy Price   <input type="textbox" ng-model="share.BuyPrice"/><br/> 
Sell Price  <input type="textbox" ng-model="share.SellPrice"/><br/> 
Quantity    <input type="textbox" ng-model="share.Quantity"/><br/> 

Таким образом, значения доли будут автоматически обновляться без необходимости использования $watch или сеттеров и геттеров. Однако он не будет автоматически вызывать function(){ return ( $scope.SellValue() - $scope.BuyValue() )}; опять таки

Для этого я бы сделал

Buy Price   <input type="textbox" ng-model="share.BuyPrice" ng-change="updatePrices()"/><br/> 
Sell Price  <input type="textbox" ng-model="share.SellPrice" ng-change="updatePrices()"/><br/> 
Quantity    <input type="textbox" ng-model="share.Quantity" ng-change="updatePrices()"/><br/> 

а также

$scope.updatePrices=function(){
  $scope.share.BuyValue = function(){ return ( $scope.share.BuyPrice * $scope.share.Quantity )};
  $scope.share.SellValue = function(){ return ( $scope.share.SellPrice * $scope.share.Quantity )};
  $scope.share.Profit = function(){ return ( $scope.share.SellValue() - $scope.share.BuyValue() )};
}
person Jegsar    schedule 18.07.2014