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">

https://plnkr.co/edit/OfhoxXYCbf7AFYiAd5zL?p=preview