Директива AngularJS - ng-class в ng- repeat - это должен быть $watcher для переключения стиля?
В настоящее время я реализую шип, чтобы углубить мое понимание угловых директив и т. Д.
Предпосылка состоит в том, чтобы создать список наблюдения FX по ряду валютных пар.
Мой фид данных настроен для моих обновлений цен через socket.io.
Камнем преткновения, который у меня есть, является возможность изменять CSS в зависимости от изменения цены, то есть стрелка вверх для вверх, стрелка вниз для вниз.
Я чувствую, что мне нужна функция наблюдателя, но я не мог понять, с чего начать, поэтому искал какое-то выражение в ng-классе, чтобы выполнить работу... но метод не только начал выглядеть как $watcher, но и был ошибочным поскольку сохранение предыдущей цены в моей директиве означало, что всегда было только одно старое значение, а не одно для каждой цены.
Вот мой вопрос: есть ли решение с помощью ng-class или в настройке функции $watcher?
Вот мой код...
HTML шаблон
<div ng-repeat="rate in rates" ng-click="symbolSelected(rate)">
<div class="col-1-4">
{{rate.symbol}}
</div>
<div class="col-1-4">
<span ng-class='bullBear(rate.bidPoint)' ></span> {{rate.bidBig}}<span class="point">{{rate.bidPoint}}</span>
</div>
<div class="col-1-4">
<span ng-class='bullBear(rate.offerPoint)' ></span> {{rate.offerBig}}<span class="point">{{rate.offerPoint}}</span>
</div>
<div class="col-1-4">
{{rate.timeStamp | date : 'hh:mm:ss'}}
</div>
</div>
Моя директива в настоящее время выглядит следующим образом... как уже отмечалось, это не будет работать, а метод bullBear начинал выглядеть как функция $watcher.
.directive('fxmarketWatch', function(fxMarketWatchPriceService){
return {
restrict:'E',
replace:'true',
scope: { },
templateUrl:'common/directives/fxMarketWatch/marketwatch.tpl.html',
controller : function($scope, SYMBOL_SELECTED_EVT,fxMarketWatchPriceService){
$scope.symbolSelected = function(currency){
$scope.$emit(SYMBOL_SELECTED_EVT,currency);
}
$scope.bullBear = function(newPrice){
if ($scope.oldPrice> newPrice ){
return ['glyphicon glyphicon-arrow-down','priceDown'];
}
else if ($scope.oldPrice > newPrice ){
return ['glyphicon glyphicon-arrow-up','priceUp'];
}
}
$scope.$on('socket:fxPriceUpdate', function(event, data) {
$scope.rates = data.payload;
});
}
}
})
2 ответа
Я рекомендую вам использовать оба ng-class
а также $watcher
, Эти два могут фактически дополнить друг друга:
ОБНОВЛЕНИЕ: чтобы код работал с ng-repeat
нам нужно перенести всю логику CSS классов на другую controller
:
app.controller('PriceController', function($scope) {
// we first start off as neither up or down
$scope.cssBid = 'glyphicon';
$scope.cssOffer = 'glyphicon';
var cssSetter = function(newVal, oldVal, varName) {
if (angular.isDefined(oldVal) && angular.isDefined(newVal)) {
if (oldVal > newVal) {
$scope[varName] = 'glyphicon glyphicon-arrow-down priceDown';
} else if (newVal > oldVal) {
$scope[varName] = 'glyphicon glyphicon-arrow-up priceUp';
} else {
$scope[varName] = 'glyphicon';
}
}
};
// watch for change in 'rate.bidPoint'
$scope.$watch('rate.bidPoint', function(newVal, oldVal) {
cssSetter(newVal, oldVal, 'cssBid');
});
// watch for change in 'rate.offerPoint'
$scope.$watch('rate.offerPoint', function(newVal, oldVal) {
cssSetter(newVal, oldVal, 'cssOffer');
});
});
Далее мы связываем это PriceController
на ng-repeat
дела. Тем самым Angular создаст один controller
экземпляр для каждого rate
в rates
, Итак, на этот раз rate.bidPoint
а также rate.offerPoint
должен быть доступен для $watch
-ную:
<div ng-repeat="rate in rates" ng-click="symbolSelected(rate)" ng-controller="PriceController">
<div class="col-1-4">
<span ng-class='cssBid'></span> {{rate.bidBig}}<span class="point">{{rate.bidPoint}}</span>
</div>
<div class="col-1-4">
<span ng-class='cssOffer'></span> {{rate.offerBig}}<span class="point">{{rate.offerPoint}}</span>
</div>
</div>
Теперь контроллер директивы будет намного короче, чем раньше:
controller: function($scope, SYMBOL_SELECTED_EVT, fxMarketWatchPriceService){
$scope.symbolSelected = function(currency) {
$scope.$emit(SYMBOL_SELECTED_EVT, currency);
}
$scope.$on('socket:fxPriceUpdate', function(event, data) {
$scope.rates = data.payload;
});
}
Вы можете изменить ng-class
и переместите логику в представление, потому что стили и размещение классов не должны выполняться в коде.
<div class="col-1-4">
<span class="glyphicon" ng-class="{'glyphicon-arrow-up priceUp': oldPrice > rate.bidPoint, 'glyphicon-arrow-down priceDown':oldPrice > rate.bidPoint}"></span> {{rate.bidBig}}<span class="point">{{rate.bidPoint}}</span>
</div>
Или вот так:
<span class="glyphicon {{oldPrice > rate.bidPoint ? 'glyphicon-arrow-down priceDown':'glyphicon-arrow-up priceUp'}}></span> {{rate.bidBig}}<span class="point">{{rate.bidPoint}}</span>