簡體   English   中英

在指令中調用時,Angular JS控制器元素未定義

[英]Angular JS controller element is undefined when called in directive

我有一個像這樣的控制器:

myApp.controller('WizardController', function ($scope, $http) {

$scope.user = {
    addressline1: null,
    cobuyer: null,
    validate: null,
    cobuyerfirstname: null,
    cobuyerlastname: null,
    cobuyeremail: null,
    cobuyerdob: null,
    cobuyeraddressline1: null,
    cobuyeraddressline2: null,
    cobuyercity: null,
    cobuyerprovince: null,
    cobuyerpostalcode: null,
    cobuyerphone: null,
    dobString: null,
    cobuyerDobString: null,
    isWaitList: false
};

});

我在下面添加此指令:

myApp.directive('checkbox', function () {
    return {
        restrict: 'A',
        replace: false,
        transclude: true,
        scope: {
            user: '='
        },
        template: '<label for="addressSame" class="form-label col-md-2" style="width: auto;">Same as Buyers Address</label><input type="checkbox" name="addressSame" ng-click="isSameAddress()" ng-model="isChecked" />',
        link: function (scope, element, attrs) {
            // Initialize to unchecked
            scope.isChecked = false;

        },
        controller: function ($scope) {

            $scope.isSameAddress = function () {

                console.log($scope.isChecked);

                if ($scope.isChecked == true) {
                    console.log($scope.user);
                }
                else {

                }
            }

        }
    }
});

現在,我的復選框應有應有的出現,我可以對其進行檢查並從scope.isChecked中獲取是或否。 我現在正在嘗試從$ scope.user獲取項目,但是它說它是未定義的。 我對Angular JS相當陌生,我不知道如何解決此問題...如何獲取在控制器中定義的元素?

我也嘗試過此操作,但仍未定義:

myApp.directive('checkbox', function () {
    return {
        restrict: 'A',
        replace: false,
        transclude: true,
        scope: {
            user: '='
        },
        template: '<label for="addressSame" class="form-label col-md-2" style="width: auto;">Same as Buyers Address</label><input type="checkbox" name="addressSame" ng-click="isSameAddress()" ng-model="isChecked" />',
        link: function (scope, element, attrs) {
            // Initialize to unchecked
            scope.isChecked = false;

        },
        controller: function ($scope, $http, $rootScope) {

            $scope.isSameAddress = function () {

                console.log($scope.isChecked);

                if ($scope.isChecked == true) {
                    console.log($rootScope.user);
                }
                else {

                }
            }

        }
    }
});

這是因為$scope僅在控制器本身內部可見。 您可以使用$rootScope (只需要記住它是一個全局變量)即可; 嘗試從$scope.user更改為$rootScope.user

嘗試這個

myApp.controller('WizardController', ['$scope', function ($scope, $http) {

$scope.user = {
    addressline1: null,
    cobuyer: null,
    validate: null,
    cobuyerfirstname: null,
    cobuyerlastname: null,
    cobuyeremail: null,
    cobuyerdob: null,
    cobuyeraddressline1: null,
    cobuyeraddressline2: null,
    cobuyercity: null,
    cobuyerprovince: null,
    cobuyerpostalcode: null,
    cobuyerphone: null,
    dobString: null,
    cobuyerDobString: null,
    isWaitList: false
};

}]);

 var app = angular.module('plunker', []); app.directive('checkbox', function () { return { restrict: 'A', replace: false, transclude: true, $scope: { user: '=' }, template: '<label for="addressSame" class="form-label col-md-2" style="width: auto;">Same as Buyers Address</label><input type="checkbox" name="addressSame" ng-click="isSameAddress()" ng-model="isChecked" /> <span ng-if="isChecked"> {{user|json}}</span>', link: function ($scope, element, attrs) { // Initialize to unchecked $scope.isChecked = false; console.log($scope.user) }, controller: function ($scope) { $scope.isSameAddress = function () { console.log($scope.isChecked); if ($scope.isChecked === true) { console.log($scope.user); } else { } } } } }); app.controller('MainCtrl', function ($scope, $http) { $scope.user = { addressline1: null, cobuyer: null, validate: null, cobuyerfirstname: null, cobuyerlastname: null, cobuyeremail: null, cobuyerdob: null, cobuyeraddressline1: null, cobuyeraddressline2: null, cobuyercity: null, cobuyerprovince: null, cobuyerpostalcode: null, cobuyerphone: null, dobString: null, cobuyerDobString: null, isWaitList: false }; }); 
 <!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.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script> <script src="app.js"></script> </head> <body ng-controller="MainCtrl"> <p checkbox="user">Hello</p> </body> </html> 

由於您未提供任何其他代碼,因此很難確切地知道您在做什么。 所以我做了一些假設:

  • 我假設您的控制器WizardController是外部控制器。
  • 我認為您確實沒有在使用轉寫,因為您的模板沒有使用轉寫。 所以我從指令中刪除了transclude: true
  • 我格式化了代碼以適合我的風格。 我發現從角度定位代碼中更容易了解我的功能。 並將它們組合在一起。 如果您打算這樣做,我還添加了代碼來處理縮小。
  • 我從未將控制器代碼嵌入指令中。 這更符合“ 單一責任原則”

我將在下面提供更多詳細信息。

這是我的代碼:

<!DOCTYPE html>
<html ng-app="myApp">
  <head>
    <title>AngularJS Example</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js"></script>
    <script>
    // Controller code for application
    AppController.$inject = ['$scope', '$http']; // <- This is needed only if you plan to minify your JS code.
    function AppController($scope, $http) {
      $scope.user = {
        addressline1: '', // <-- Since these values will display in the HTML use an empty string instead of null
        cobuyer: '',
        validate: '',
        cobuyerfirstname: 'John',
        cobuyerlastname: 'Smith',
        cobuyeremail: 'myEmail@example.com',
        cobuyerdob: '',
        cobuyeraddressline1: '123 Some Street',
        cobuyeraddressline2: '',
        cobuyercity: 'Anchorage',
        cobuyerprovince: '',
        cobuyerpostalcode: '99501',
        cobuyerphone: '',
        dobString: '',
        cobuyerDobString: '',
        isWaitList: false
      };
    }

    // Controller code for directive `checkbox`
    CheckboxController.$inject = ['$scope']; // <- This is needed only if you plan to minify your JS code.
    function CheckboxController($scope) {
      $scope.isChecked = false; // <-- Put all scope variables into the controller.

      $scope.isSameAddress = function () { // <-- put all of your scope functions in the controller.
        console.log('$scope.isChecked', $scope.isChecked);

        if ($scope.isChecked == true) {
          console.log('$scope.user', $scope.user);
        }
        else {

        }
      }
    }

    // Directive code for attribute `checkbox`
    function checkboxDirective() {
      return {
        controller: 'CheckboxController', // <-- I link to my controller and avoid adding the controller code here.
        restrict: 'A',
        replace: false,
        scope: {
          user: '='
        },
        template: '<label for="addressSame" class="form-label col-md-2" style="width: auto;">Same as Buyers Address</label><input type="checkbox" name="addressSame" ng-click="isSameAddress()" ng-model="isChecked" />'
      }
    }

    // Angular registration code
    var myApp = angular.module('myApp', []);

    myApp.controller('AppController', AppController);
    myApp.controller('CheckboxController', CheckboxController);
    myApp.directive('checkbox', checkboxDirective);
    </script>
  </head>
  <body ng-controller="AppController">
    <div checkbox user="user"></div>
  </body>
</html>

在您的示例中,您沒有向我們展示如何將user吸引到您的指令中。 根據您的代碼示例,它應該已經通過user屬性傳遞了。 像這樣:

<div checkbox user="user"></div>

由於您使用的是基於Attribute的指令,因此還可以使用checked屬性而不是user屬性,如下所示:

// Directive code for attribute `checkbox`
function checkboxDirective() {
  return {
    controller: 'CheckboxController', // <-- I link to my controller and avoid adding the controller code here.
    restrict: 'A',
    replace: false,
    scope: {
      user: '=checkbox'
    },
    template: '<label for="addressSame" class="form-label col-md-2" style="width: auto;">Same as Buyers Address</label><input type="checkbox" name="addressSame" ng-click="isSameAddress()" ng-model="isChecked" />'
  }
}

這將允許您通過checkbox屬性將外部控制器的user值獲取到指令中。 然后,可以通過$scope.user屬性在您的Directive JS代碼中訪問此值。 像這樣:

<div checkbox="user"></div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM