选项卡内的表单字段控制器

时间:2015-08-14 23:02:17

标签: angularjs forms

我在为表单字段创建指令时遇到问题。我试图达到的目标是在$ viewValue改变时更改指令链接功能中的一些工厂数据。这是代码:

HTML:



<!DOCTYPE html>
<html ng-app="plunker">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker</title>
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
  <link rel="stylesheet" href="style.css" />
  <script data-require="angular.js@1.4.x" src="https://code.angularjs.org/1.4.3/angular.js" data-semver="1.4.3"></script>
  <script data-require="angular-aria@1.4.1" data-semver="1.4.1" src="https://code.angularjs.org/1.4.1/angular-aria.js"></script>
  <script data-require="angular-animate@1.4.1" data-semver="1.4.1" src="https://code.angularjs.org/1.4.1/angular-animate.js"></script>
  <link data-require="angular-material@0.10.0" data-semver="0.10.0" rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/0.10.0/angular-material.min.css" />
  <script data-require="angular-material@0.10.0" data-semver="0.10.0" src="https://ajax.googleapis.com/ajax/libs/angular_material/0.10.0/angular-material.min.js"></script>
  <script src="app.js"></script>
  <script src="factory.js"></script>
  <script src="directive.js"></script>
</head>

<body ng-controller="MainCtrl">
  <md-tabs>
    <md-tab label="TAB1">
      <p>
        Click TAB2. Then click "conslole log" button. You will see the output. Go back to TAB1 and repeat previous actions. Look at the output. What the hell?!
      </p>
    </md-tab>
    <md-tab label="TAB2">
      <form>
        <br>
        <input name="input" ng-model="model.number" test-directive="model">
        <p>
          Model: {{model}}
        </p>
      </form>
      <md-button ng-click="increment()" class="md-primary md-raised">Console log</md-button>
    </md-tab>
  </md-tabs>
</body>

</html>
&#13;
&#13;
&#13;

app.js:

&#13;
&#13;
var app = angular.module('plunker', ['ngMaterial', 'ngAnimate']);

app.controller('MainCtrl', ['$scope', 'TestFactory',
  function($scope, TestFactory) {
    $scope.model = TestFactory;
    $scope.increment = function() {
      TestFactory.increment();
    }
  }
]);
&#13;
&#13;
&#13;

directive.js:

&#13;
&#13;
angular.module('plunker').directive('testDirective', function() {
  return {
    restrict: 'A',
    scope: {
      data: '=testDirective'
    },
    require: 'ngModel',
    link: function(scope, elem, attr, ctrl) {
      var n = 1;
      scope.$watch(function() {
        return ctrl.$viewValue
      }, function() {
        console.log(scope.data);
        scope.data.error = !scope.data.error;
        console.log("This function triggered " + n + " times.");
        n++;
      });
    }
  }
})
&#13;
&#13;
&#13;

factory.js:

&#13;
&#13;
angular.module('plunker').factory('TestFactory', function() {
  Data = {};
  Data.number = 1;
  Data.error = true;
  Data.increment = function() {
    Data.number++;
  }
  return Data
})
&#13;
&#13;
&#13;

我创建了一个带有应用程序结构简化副本的plunker: http://plnkr.co/edit/hXFZZ6sM4myGOwMHazd6?p=preview

据我所知,问题是每次切换标签时,都会创建一个新的ctrl。有没有可能阻止这种奇怪的行为?

1 个答案:

答案 0 :(得分:0)

看起来问题是手表正在重新注册。您可以检查它是否已经注册,或者在$ desroy上取消注册。

// Popup the login
private void loginPopup(){

    // Get the contents
    RelativeLayout loginLayout = (RelativeLayout) findViewById(R.id.login_popup_layout);
    EditText usernameTxt = (EditText) findViewById(R.id.login_popup_username);
    EditText passwordTxt = (EditText) findViewById(R.id.login_popup_password);
    Button registerBtn = (Button) findViewById(R.id.login_popup_register);
    Button loginBtn = (Button) findViewById(R.id.login_popup_login);
    Button GloginBtn = (Button) findViewById(R.id.login_popup_G);
    Button FBloginBtn = (Button) findViewById(R.id.login_popup_FB);

    //loginLayout.addView(usernameTxt);

    // Popup the login menu
    //View popupView = getLayoutInflater().inflate(R.layout.login_popup_layout, null);
    PopupWindow loginPopup;
    loginPopup = new PopupWindow(loginLayout, 100, 100);// The last true is to make it focusable
    loginPopup.setWindowLayoutMode(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
    //loginPopup.setContentView(loginLayout);

    // Center the popup and display it.
    Display display = getWindowManager().getDefaultDisplay();
    Point size=new Point();
    display.getSize(size);
    loginPopup.showAtLocation((RelativeLayout)findViewById(R.id.displayLayout), Gravity.NO_GRAVITY, 50,50 );//(size.x/2)-loginPopup.getWidth()/2 , (size.y/2)-loginPopup.getHeight()/2 );}