Angularjs:自定义双向绑定属性指令
Angularjs: custom two-way binding attribute directive
我必须编写一个具有以下行为的指令:
控制器:
vm.mymodel = 'Hello World'
Html:
<custom-input mydirective="{propbind: 'data-value', propmodel: vm.mymodel}"></custom-input>
我希望我的自定义输入转换如下:
<custom-input data-value="{{vm.mymodel}}"></custom-input>
- 当我从控制器更新 vm.mymodel 时,数据值属性必须更改。
- 当我更新数据值时,vm.mymodel 也必须更新。
- 我不能在自定义输入上使用 ng-mmodel 指令(它使用数据值,并应用了内部函数)
这就是我尝试做的事情:
- 在我的指令的编译函数中,将 scope.propbind 属性值设置为“{{propmodel}}”,然后删除 "mydirective" 属性。但我似乎无法访问这里的范围。但是,如果我使用 element.attr('data-value', 'hello world') 我可以看到我的数据值正确设置
- 我试图在 link 函数中做同样的事情,但是我的范围的值是未定义的
- 我也在控制器函数中尝试过,但我的作用域也是空的,而且我无法访问 attr 或元素。
var app = angular.module('myApp', []);
app.controller('myctrl', function($scope) {
var vm = this;
this.mymodel = 'Hello world !';
});
app.directive('mydirective', function () {
return {
restrict: 'A',
replace: false,
transclude: false,
scope: {
bindingvalue: '='
},
compile: function(element) {
//remove the element for clarity
element.removeAttr('mydirective');
},
link: function($scope, elem, attr) {
//set the attribute
attr.$set($scope.bindingvalue.propbind, $scope.bindingvalue.propmodel);
//Observe the attribute value for changes
attr.$observe($scope.bindingvalue.propbind, function(value) {
$scope.bindingvalue.propmodel = value;
})
},
controller: function($scope, $element) {
//Nothing here yet
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myctrl as vm">
<input mydirective="{propbind: 'data-value', propmodel: vm.mymodel}" type="text"/>
model value : {{vm.mymodel}}
</div>
你能帮帮我吗?我的逻辑对我的问题有好处吗?我认为如果我设法在我的 link 函数中获得我的范围值,everythink 就可以工作。
谢谢
这应该有效:
var app = angular.module('myApp', []);
app.controller('myctrl', function($scope) {
var vm = this;
vm.mymodel = 'Hello world !';
});
app.directive('customInput', function () {
return {
restrict: 'EA',
scope: {
value: '='
},
template: '<input type="text" ng-model="value" />',
controller: function($scope, $element) {
//Nothing here yet
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myctrl as vm">
<custom-input data-value="vm.mymodel"> </custom-input>
model value : {{vm.mymodel}}
</div>
我终于成功了。这是我的解决方案:
var app = angular.module('myApp', []);
app.controller('myctrl', function ($scope) {
var vm = this;
vm.mymodel = 'Hello world !';
vm.changeModel = function() {
vm.mymodel = 'New Value'
console.log(document.getElementById('myinput'))
}
vm.changeAttribute = function() {
document.getElementById('myinput').setAttribute('data-value', '123456789');
console.log(document.getElementById('myinput'))
}
});
app.directive('mydirective', function ($timeout, $interval) {
return {
restrict: 'A',
replace: false,
transclude: false,
scope: {
propbind: '@',
model: '='
},
link: function (scope, elem, attr) {
attr.$set(scope.propbind, scope.model);
//Watch model for changes, and update attribute
scope.$watch(function () {
return scope.model
}, function () {
attr.$set(scope.propbind, scope.model);
});
//Watch for changes in attribute, and update model
scope.$watch(function () {
return elem[0].getAttribute(scope.propbind);
}, function (value) {
$timeout(function () {
scope.model = value;
});
});
//Get attribute value for angularjs to reevaluate dom
$interval(function () {
var val = elem[0].getAttribute(scope.propbind)
}, 100);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myctrl as vm">
<input id="myinput" mydirective propbind="data-value" model="vm.mymodel" type="text"/>
model value : {{vm.mymodel}}
<div>
<button ng-click="vm.changeModel()">change model value</button>
<button ng-click="vm.changeAttribute()">change model value</button>
</div>
{{document.getElementById('myinput')}}
</div>
该演示使用基本输入而不是我的自定义输入,因此它实际上并未绑定到数据值属性。
但是,您可以单击这两个按钮来更新控制器中的模型或数据值属性。
您可以看到,如果我更改控制器中的值,数据值就会更新。
此外,如果您更新输入的数据值,模型会在控制器中更新。
我必须编写一个具有以下行为的指令:
控制器:
vm.mymodel = 'Hello World'
Html:
<custom-input mydirective="{propbind: 'data-value', propmodel: vm.mymodel}"></custom-input>
我希望我的自定义输入转换如下:
<custom-input data-value="{{vm.mymodel}}"></custom-input>
- 当我从控制器更新 vm.mymodel 时,数据值属性必须更改。
- 当我更新数据值时,vm.mymodel 也必须更新。
- 我不能在自定义输入上使用 ng-mmodel 指令(它使用数据值,并应用了内部函数)
这就是我尝试做的事情:
- 在我的指令的编译函数中,将 scope.propbind 属性值设置为“{{propmodel}}”,然后删除 "mydirective" 属性。但我似乎无法访问这里的范围。但是,如果我使用 element.attr('data-value', 'hello world') 我可以看到我的数据值正确设置
- 我试图在 link 函数中做同样的事情,但是我的范围的值是未定义的
- 我也在控制器函数中尝试过,但我的作用域也是空的,而且我无法访问 attr 或元素。
var app = angular.module('myApp', []);
app.controller('myctrl', function($scope) {
var vm = this;
this.mymodel = 'Hello world !';
});
app.directive('mydirective', function () {
return {
restrict: 'A',
replace: false,
transclude: false,
scope: {
bindingvalue: '='
},
compile: function(element) {
//remove the element for clarity
element.removeAttr('mydirective');
},
link: function($scope, elem, attr) {
//set the attribute
attr.$set($scope.bindingvalue.propbind, $scope.bindingvalue.propmodel);
//Observe the attribute value for changes
attr.$observe($scope.bindingvalue.propbind, function(value) {
$scope.bindingvalue.propmodel = value;
})
},
controller: function($scope, $element) {
//Nothing here yet
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myctrl as vm">
<input mydirective="{propbind: 'data-value', propmodel: vm.mymodel}" type="text"/>
model value : {{vm.mymodel}}
</div>
你能帮帮我吗?我的逻辑对我的问题有好处吗?我认为如果我设法在我的 link 函数中获得我的范围值,everythink 就可以工作。
谢谢
这应该有效:
var app = angular.module('myApp', []);
app.controller('myctrl', function($scope) {
var vm = this;
vm.mymodel = 'Hello world !';
});
app.directive('customInput', function () {
return {
restrict: 'EA',
scope: {
value: '='
},
template: '<input type="text" ng-model="value" />',
controller: function($scope, $element) {
//Nothing here yet
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myctrl as vm">
<custom-input data-value="vm.mymodel"> </custom-input>
model value : {{vm.mymodel}}
</div>
我终于成功了。这是我的解决方案:
var app = angular.module('myApp', []);
app.controller('myctrl', function ($scope) {
var vm = this;
vm.mymodel = 'Hello world !';
vm.changeModel = function() {
vm.mymodel = 'New Value'
console.log(document.getElementById('myinput'))
}
vm.changeAttribute = function() {
document.getElementById('myinput').setAttribute('data-value', '123456789');
console.log(document.getElementById('myinput'))
}
});
app.directive('mydirective', function ($timeout, $interval) {
return {
restrict: 'A',
replace: false,
transclude: false,
scope: {
propbind: '@',
model: '='
},
link: function (scope, elem, attr) {
attr.$set(scope.propbind, scope.model);
//Watch model for changes, and update attribute
scope.$watch(function () {
return scope.model
}, function () {
attr.$set(scope.propbind, scope.model);
});
//Watch for changes in attribute, and update model
scope.$watch(function () {
return elem[0].getAttribute(scope.propbind);
}, function (value) {
$timeout(function () {
scope.model = value;
});
});
//Get attribute value for angularjs to reevaluate dom
$interval(function () {
var val = elem[0].getAttribute(scope.propbind)
}, 100);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myctrl as vm">
<input id="myinput" mydirective propbind="data-value" model="vm.mymodel" type="text"/>
model value : {{vm.mymodel}}
<div>
<button ng-click="vm.changeModel()">change model value</button>
<button ng-click="vm.changeAttribute()">change model value</button>
</div>
{{document.getElementById('myinput')}}
</div>
该演示使用基本输入而不是我的自定义输入,因此它实际上并未绑定到数据值属性。 但是,您可以单击这两个按钮来更新控制器中的模型或数据值属性。 您可以看到,如果我更改控制器中的值,数据值就会更新。 此外,如果您更新输入的数据值,模型会在控制器中更新。