AngularJS ngModel не работает внутри кисти ui-bootstrap

Следующий код иллюстрирует проблему:

<!DOCTYPE html>
<html ng-app="plunker">
  <head>
    <title>AngularJS Plunker</title>
    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
    <script src="https://code.angularjs.org/1.3.6/angular.js"></script>
    <script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.0.min.js"></script>
    <script>
angular.module('plunker', ['ui.bootstrap'])
.controller('MainCtrl', function($scope) {
  $scope.changes = 0;
  $scope.updateValueInScope = function () {
    $scope.valueInScope = $scope.value;
    $scope.changes++;
  }
});
    </script>
  </head>

  <body ng-controller="MainCtrl">
    <tabset>
      <tab heading="Tab A">
        <div class="panel">
          <input type="text" ng-model="value" ng-change="updateValueInScope()" />
          <br />
          <tt>value: {{value}}</tt><br />
          <tt>valueInScope: {{valueInScope}}</tt><br />
          <tt>changes: {{changes}}</tt>
        </div>
      </tab>
    </tabset>
    <input type="text" ng-model="value" ng-change="updateValueInScope()" />
    <br />
    <tt>value: {{value}}</tt><br />
    <tt>valueInScope: {{valueInScope}}</tt><br />
    <tt>changes: {{changes}}</tt>
  </body>

</html>

Plunker здесь:

http://plnkr.co/edit/dJc009csXVHc7PLSyCf4?p=preview

Это создает два текстовых поля: один внутри табуляции и один внешний. Они оба связаны с переменной области value. Обновление содержимого текстового поля внутри табуляции не обновляет переменную value в области. Обновление текстового поля вне табуляции. Изменения в любом из текстовых полей приведут к вызову updateValueInScope() через ngChange.

Может кто-нибудь объяснить мне, почему это так ведет себя? Есть ли способ "исправить" поведение, чтобы текстовое поле внутри табуляции изменило модель в области?

Ответ 1

Почти наверняка проблема в том, что вы пытаетесь привязать к примитиву (в данном случае float). Что-то вроде этого должно это исправить.

$scope.data = {}
$scope.updateValueInScope = function () {
  $scope.data.valueInScope = $scope.data.value;
  $scope.changes++;
}

В основном в angular, если вы привязываетесь к примитиву, значение переменной передается, а не ссылка на нее, которая может прерывать двухстороннюю привязку. Я предполагаю, что директива tabset создает свою собственную область видимости, поэтому переменная valueInScope, определенная в контроллере, теряет привязку в дочерней области tabset, потому что ее примитив. Во всяком случае, не связывайтесь с примитивами, и он должен работать.

Вот фиксированная версия plunk