Angularjs 在Angular中,范围变量*before*ngModel绑定输入的bind属性’;s`值`

Angularjs 在Angular中,范围变量*before*ngModel绑定输入的bind属性’;s`值`,angularjs,data-binding,angular-ngmodel,Angularjs,Data Binding,Angular Ngmodel,在我的Angular应用程序中,我定义了一个自定义滑块指令,用于包装。我的自定义指令支持ngModel将滑块的值绑定到变量。自定义指令还需要分数大小属性。它对值进行计算,然后使用结果设置已包装的的步骤值 当我结合这两个特性时,我看到了一个bug—ngModel和我的绑定属性值。它们按错误的顺序运行 下面是一个演示: angular.module('HelloApp',[]); angular.module('HelloApp').directive('customSlider',functio

在我的Angular应用程序中,我定义了一个自定义滑块指令,用于包装。我的自定义指令支持
ngModel
将滑块的值绑定到变量。自定义指令还需要
分数大小
属性。它对值进行计算,然后使用结果设置已包装的
步骤

当我结合这两个特性时,我看到了一个bug—
ngModel
和我的绑定属性值。它们按错误的顺序运行

下面是一个演示:

angular.module('HelloApp',[]);
angular.module('HelloApp').directive('customSlider',function(){
var tpl=“2 3”;
返回{
限制:'E',
模板:第三方物流,
要求:'ngModel',
范围:{
分形大小:'='
},
链接:函数(范围、元素、属性、ngModelCtrl){
scope.stepSize=1/scope.fractionSize;
范围.$watch('theNum',函数(newValue,oldValue){
ngModelCtrl.$setViewValue(newValue);
});
ngModelCtrl.$render=function(){
scope.theNum=ngModelCtrl.$viewValue;
};
}
};
});
角度.module('HelloApp')。控制器('HelloController',函数($scope){
$scope.someNumber=2.5;
});

自定义滑块
查看/编辑滑块的值

我不确定这是否是正确的方法,但向主控制器添加超时可以解决问题

$timeout(function() {
    $scope.someNumber = 2.5;
});

编辑:虽然一开始它看起来像是一个肮脏的黑客,但请注意,(final)$scope变量的分配通常晚于模板,因为需要额外的ajax调用来检索值。

链接
函数中,通过添加
步骤
属性来操作DOM

您还可以通过将
theNum:'=ngModel'
放入
scope
中,简化与外部
ngModel
的绑定

var-app=angular.module('HelloApp',[]);
应用程序指令('customSlider',函数(){
var tpl=“2 3”;
返回{
限制:'E',
模板:第三方物流,
要求:'ngModel',
范围:{
fractionSize:“=”,
theNum:'=ngModel'
},
链接:函数(范围、元素、属性、ngModelCtrl){
var e=element.find('input')[0];
var step=1/scope.fractionSize;
e、 setAttribute('步骤',步骤);
范围.$watch('fractionSize',函数(newVal){
if(newVal){
var阶跃=1/newVal;
e、 setAttribute('步骤',步骤);
}
});
}
};
});
角度.module('HelloApp')。控制器('HelloController',函数($scope){
$scope.someNumber=2.5;
});

自定义滑块
查看/编辑滑块的值
{{someNumber}}
进一步考虑直接DOM操作,我根本不会在内部输入上使用另一个
ng模型
,而是始终直接设置/获取输入上的属性

  • 在设置/获取输入值时,需要考虑一个抽象级别。原始DOM事件和元素

  • 因此,您不局限于Angular在这些元素上所允许的内容(事实上:它所做的事情似乎无法在没有解决方法的情况下处理您的用例)。如果浏览器允许在范围输入上执行此操作,则可以执行此操作

  • 在设置一个值的one UI小部件上使用2个NGModelController可能会有点混乱,至少对我来说是这样

  • 如果需要/想要使用,您仍然可以访问外部ngModelController管道及其有关解析器和验证器的所有功能

  • 您可以节省额外的观察者(但这可能是一个微小的/过早的优化)

请参见下面的示例

angular.module('HelloApp',[]);
angular.module('HelloApp').directive('customSlider',function(){
var tpl=“2 3”;
返回{
限制:'E',
模板:第三方物流,
要求:'ngModel',
范围:{
分形大小:'='
},
链接:函数(范围、元素、属性、ngModelCtrl){
var input=element.find('input');
input.prop('step',1/范围.fractionSize);
on('input',function(){
作用域$apply(函数(){
ngModelCtrl.$setViewValue(input.prop('value'));
});
});
ngModelCtrl.$render=函数(值){
input.prop('value',ngModelCtrl.$viewValue);
};
}
};
});
角度.module('HelloApp')。控制器('HelloController',函数($scope){
$scope.someNumber=2.5;
});

自定义滑块
查看/编辑滑块的值

恐怕这不适合我。在我的real应用程序中,滑块是通过
ngRepeat
指令添加到页面上的,以响应用户发起的将数字添加到数组上的操作。因此,我的应用程序相当于
$scope.someNumber
在创建编辑它的滑块之前始终存在。而且我的应用程序已经完全离线了,所以超时是不合适的。看起来它被提升为一个新的应用程序。您可能需要参考其中的临时解决方案。
作用域。$apply
似乎是不必要的–即使没有
作用域,
输入
处理程序仍然可以工作。$apply
。我认为这是因为,
ngModelCtrl.$setViewValue
在运行时触发了一个
$digest
。使用
scope.$apply
处理DOM“以防万一”是否是一种好做法,即使当前代码不需要这样做?@RoryO'Kane我认为