在指令的属性中观察和评估表达式

时间:2014-10-02 00:32:23

标签: angularjs angularjs-directive

(我不能让标题更短,因为我真的想一下子做所有事情。)

我想做的是:

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

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

每当这些表达式的结果发生变化时,指令都需要更新内容。有一个单选按钮可以在两个值之间切换scopevar,当发生这种情况时,mySlidermyOtherDirective都应该改变它们的工作方式;滑块获得不同的最大值和不同的步长,而另一个指令获得了在某些计算中使用的不同因子。

目前,我依靠

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

适用于stepfactor,但对于maxnewVal神秘地变为NaN。并且scopefunction()实际上总是返回一个数字。那怎么可能NaNmax案例与其他案件有何不同?

我的指令都有隔离范围。 scopefunction()是父作用域的函数,因此无法从指令内部调用它。我不希望这样,因为我希望指令尽可能通用,因为它们被重用了很多。在大多数地方,它们不会用于这些计算,因此我希望保持这些属性的使用方式尽可能简单和干净。

我已经尝试过和没有

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

这似乎并不重要,因为我已经直接使用attr.max

我很难过。为什么max有所不同?怎么可能不起作用?

添加:问题似乎是'scopefunction(scopevar)'被评估为'undefined',当我乘以它时会产生NaN。我仍然不明白为什么它在factorstep中有用。

我让a plnkr显示最大失败并且步骤成功。不幸的是,我再也无法重现factor了。至少没有隔离范围。当我删除隔离范围时,factor有效。这表明我需要删除隔离范围,但我不确定我是否想这样做。我不希望我的指令污染父范围。

2 个答案:

答案 0 :(得分:1)

您可以告诉 $ watch 监控任何类似的表达式:

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

}, function(newVal) {

    console.log(newVal);

}

AngularJS API Reference

上有关 $ watch 的更多详情

答案 1 :(得分:-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>
指令控制器中的$ watchers确保将更新后的值转换为数字,因为"{{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);
});

我认为这就是它。我不依赖变量max的其他滑块仍然可以像往常一样工作。