Angular UI - 观察弹出框模板中输入的值
Angular UI - Watch value from input in Popover Template
我正在尝试创建一个使用 Angular Bootstrap 弹出窗口的指令,其中包含一个输入。一切正常,除了手表不触发。
这里是Plunker.
指令如下所示:
angular.module('ngUserPopover', ['ui.bootstrap'])
.directive('userPopover', function() {
return {
restrict: 'E',
scope: {
onSearch: '&',
},
templateUrl: 'myPopoverTemplate.html',
link: function (scope, element, attr) {
scope.templateUrl = 'someTemplate.html'; // url for popover content template
scope.searchText = 'Type something'; // initial sample value for input
scope.$watch(function () {
return scope.searchText;
}, function () {
// pass the new input value in the method...
console.log(scope.searchText);
});
}
}
});
myPopoverTemplate.html
看起来像:
<button uib-popover-template="templateUrl" popover-placement="right" popover-trigger="click" class="btn btn-default">Popover With Template</button>
<script id="someTemplate.html" type="text/ng-template">
<div>{{dynamicPopover.content}}</div>
<div class="form-group">
<input type="text" ng-model="searchText" class="form-control">
</div>
</script>
该按钮使用 Angular Bootstrap UI popover 指令,使用自定义模板 someTemplate.html
。
奇怪的是弹出窗口中的输入带有我指令范围的 searchText
变量中定义的值,即 'Type something', watch 执行一次(您可以在浏览器的控制台中看到),但是当您编辑输入值时,watch 不再触发。
因为我使用的是 angular bootstrap 指令,所以我认为 $watch
可以正常工作,范围变量在我的输入中用于 ng-model
,但是它不起作用(编辑输入值时未调用 console.log)。
有什么想法吗?
这是典型的JS原型继承问题。你需要让你的 ngModel
成为对象而不是原始对象,像这样:
scope.model = {
searchText: 'Type something'
};
scope.$watch(function() {
return scope.model.searchText;
},
function () {
// pass the new input value in the method...
console.log(scope.model.searchText);
});
然后更改输入的 ng-model
:
<input type="text" ng-model="model.searchText"/>
https://plnkr.co/edit/ocRBhNWLYUJ9hLE30U45?p=preview
如果你真的想让你的代码干净,你可以使用控制器而不是 link 函数来处理你的指令逻辑,那么你就不必担心对象与基元的问题。另一个改进是使用 ngChange
而不是 watcher 来处理对输入的更改:
link: function (scope, element, attr) {
scope.templateUrl = 'someTemplate.html';
},
controllerAs: '$ctrl',
controller: function($scope) {
var $ctrl = this;
$ctrl.searchText = 'Type something';
$ctrl.inputChanged = inputChanged;
function inputChanged() {
console.log($ctrl.searchText);
}
}
模板:
<input type="text"
ng-model="$ctrl.searchText"
ng-change="$ctrl.inputChanged()"
class="form-control">
我正在尝试创建一个使用 Angular Bootstrap 弹出窗口的指令,其中包含一个输入。一切正常,除了手表不触发。
这里是Plunker.
指令如下所示:
angular.module('ngUserPopover', ['ui.bootstrap'])
.directive('userPopover', function() {
return {
restrict: 'E',
scope: {
onSearch: '&',
},
templateUrl: 'myPopoverTemplate.html',
link: function (scope, element, attr) {
scope.templateUrl = 'someTemplate.html'; // url for popover content template
scope.searchText = 'Type something'; // initial sample value for input
scope.$watch(function () {
return scope.searchText;
}, function () {
// pass the new input value in the method...
console.log(scope.searchText);
});
}
}
});
myPopoverTemplate.html
看起来像:
<button uib-popover-template="templateUrl" popover-placement="right" popover-trigger="click" class="btn btn-default">Popover With Template</button>
<script id="someTemplate.html" type="text/ng-template">
<div>{{dynamicPopover.content}}</div>
<div class="form-group">
<input type="text" ng-model="searchText" class="form-control">
</div>
</script>
该按钮使用 Angular Bootstrap UI popover 指令,使用自定义模板 someTemplate.html
。
奇怪的是弹出窗口中的输入带有我指令范围的 searchText
变量中定义的值,即 'Type something', watch 执行一次(您可以在浏览器的控制台中看到),但是当您编辑输入值时,watch 不再触发。
因为我使用的是 angular bootstrap 指令,所以我认为 $watch
可以正常工作,范围变量在我的输入中用于 ng-model
,但是它不起作用(编辑输入值时未调用 console.log)。
有什么想法吗?
这是典型的JS原型继承问题。你需要让你的 ngModel
成为对象而不是原始对象,像这样:
scope.model = {
searchText: 'Type something'
};
scope.$watch(function() {
return scope.model.searchText;
},
function () {
// pass the new input value in the method...
console.log(scope.model.searchText);
});
然后更改输入的 ng-model
:
<input type="text" ng-model="model.searchText"/>
https://plnkr.co/edit/ocRBhNWLYUJ9hLE30U45?p=preview
如果你真的想让你的代码干净,你可以使用控制器而不是 link 函数来处理你的指令逻辑,那么你就不必担心对象与基元的问题。另一个改进是使用 ngChange
而不是 watcher 来处理对输入的更改:
link: function (scope, element, attr) {
scope.templateUrl = 'someTemplate.html';
},
controllerAs: '$ctrl',
controller: function($scope) {
var $ctrl = this;
$ctrl.searchText = 'Type something';
$ctrl.inputChanged = inputChanged;
function inputChanged() {
console.log($ctrl.searchText);
}
}
模板:
<input type="text"
ng-model="$ctrl.searchText"
ng-change="$ctrl.inputChanged()"
class="form-control">