2014-10-02 4 views
-1

(я не могу сделать название любого короче, потому что я действительно пытаюсь сделать все сразу.)Часов и оценивать выражение в атрибуте на директиве

То, что я хочу сделать это:

<mySlider max="25 * scopefunction(scopevar)" 
      step="scopevar=='foo'? 0.5 : 0.25"/> 

<myOtherDirective factor="0.4/scopefunction(scopevar)"/> 

Всякий раз, когда результаты этих выражений изменяются, директивам необходимо обновить материал. Там есть радиоблок, который переключает scopevar между двумя значениями, и когда это произойдет, оба mySlider и myOtherDirective должны изменить способ их работы; ползунок получает другой макс и другой шаг, а другая директива получает другой фактор, который используется в некоторых вычислениях.

На данный момент, я, опираясь на

scope.$watch(attrs.max, function(newVal) { 
    console.log(newVal); 
} 

, который прекрасно работает для step и factor, но max, newVal таинственно становится NaN. И scopefunction() действительно всегда возвращает число. Так как же это может быть NaN? Каким образом случай max отличается от других?

Мои директивы имеют изоляцию. scopefunction() - это функция в родительской области, поэтому она не может быть вызвана изнутри директивы. И я не хочу этого, потому что хочу, чтобы директивы были как можно более универсальными, потому что они многократно используются. И в большинстве случаев они не используются с этими расчетами, поэтому я хочу сохранить способ использования этих атрибутов как можно более простым и чистым извне.

Я пробовал и без

scope: { 
    max: '@', 
    step: '@' 
} 

, который, казалось, не имеет большого значения, потому что я уже использую attr.max напрямую.

Я в тупике. Почему max отличается? Как это могло бы не работать?

Дополнение: Проблема заключается в том, что «scopefunction (scopevar)» оценивается как «undefined», в результате чего NaN умножается. То, что я до сих пор не понимаю, - это то, почему он работает в factor и step.

Я сделал a plnkr, который показывает максимальный отказ и шаг вперед. К сожалению, я больше не могу воспроизводить factor. По крайней мере, не с изоляцией. Когда я удаляю область изоляции, работает factor. Это предполагает, что мне нужно удалить область изоляции, но я не уверен, что хочу это сделать. Я не хочу, чтобы мои директивы загрязняли родительскую область.

+0

Я добавил plnkr, но я не могу воспроизвести то, что, как я думал, в какой-то момент: фактор, работающий с областью выделения. Он работает без изолированной области, но я думаю, что мне действительно нужна область выделения. – mcv

+0

Думаю, мне, возможно, придется отбросить область изоляции. Проблема в том, что я не могу использовать 'scope: {ngModel: '='}' для обновления значения в области. Есть ли еще один хороший способ сделать это? – mcv

+0

Удаление области выделения, по-видимому, означает, что я не могу обновить ngModel внутри моей директивы. Для этого мне действительно нужна двусторонняя привязка, и это возможно только при использовании области выделения. Вместо этого я задаюсь вопросом, может ли пункт 8 в https://gist.github.com/CMCDragonkai/6282750 быть решением. – mcv

ответ

-1

я нашел способ, который, кажется, работает, достаточно просто и сохраняет изоляцию. scope: { max: '&'} оказался довольно бесполезным. Я до сих пор не знаю, как это использовать. Кажется, что лучше всего поставить логику в контроллер и использовать интерполяцию, одностороннюю привязку данных и $ watchers, чтобы поддерживать все в актуальном состоянии.

Контроллер:

$scope.maxFunc = function() { 
    return 25 * $scope.scopeFunction($scope.scopeVar); 
} 

$scope.stepFunc = function() { 
    if ($scope.userInputData === 'maand') { 
     return 0.5; 
    } 
    else { 
     return 0.25; 
    } 
} 

HTML:

<div slider min="0" max="{{maxFunc()}}" step="{{stepFunc()}}" ng-model="sliderValue"></div> 

$ наблюдателей в регуляторе директивы, чтобы гарантировать, что обновленные значения преобразуются в числа, потому что "{{maxFunc()}}" превратит их в строки:

$scope.$watch('min', function(min) { 
    $scope.min = $scope.parseInt(min, 1); 
}); 
$scope.$watch('max', function(max) { 
    $scope.max = $scope.parseInt(max, 10); 
}); 
$scope.$watch('step', function(step) { 
    $scope.step = $scope.parseFloat(step, 1); 
}); 

Это почти все, я думаю. Мои другие слайдеры, которые не полагаются на переменный макс, все еще работают так, как они всегда делали.

1

Вы можете сказать, что $ смотреть контролировать любое выражение как это:

scope.$watch(function() { 
    // return x + y; 
    // return myObject.myProperty; 
    // etc. 
    return myFunction(); 

}, function(newVal) { 

    console.log(newVal); 

} 

Подробнее о $ смотреть на AngularJS API Reference

+0

Интересная идея. Проблема в том, что я не могу оценить формулу внутри директивы, потому что директива изолирует область действия и не имеет доступа к родительской области. И я хотел бы сохранить его таким образом. Поэтому формулу нужно оценивать по-другому. – mcv

Смежные вопросы