简体   繁体   中英

AngularJS: Two-way data binding not finding model in Controller

  • I am writing a directive which could be used at multiple places.
  • The only requirement is that Controller using the directives will have their own model budgetCategories .

My Controller looks like

function BudgetController($scope, Budget, Category) {
        $scope.budgetCategories = [];
}

and Directive looks like

angular.module('categoryListingDirective', []).directive('categoryListing', function (Category) {
    return {
        restrict: 'A',
        replace: true,
        require: true,
        scope: {
            budgetCategories: '='
        },
        templateUrl: '../static/partials/categoryListingForm.html',
        link: function (scope, element, attrs) {
            scope.recurring = true;
            scope.allParentCategories = undefined;
            scope.categories = Category.query(function () {
                scope.allParentCategories = _.uniq(scope.categories, function (category) {
                    return  category.parent;
                });
                console.log('all parent categories:', scope.allParentCategories);
            });

            scope.subCategories = function (parentCategoryName) {
                return _.filter(scope.categories, function (category) {
                    return category.parent == parentCategoryName;
                });
            };

            scope.addBudgetCategory = function () {
                console.log('adding budgetCategory:', scope.amount);
                scope.budgetCategories.push({
                    'amount': scope.amount,
                    'category': scope.subCategory ? scope.subCategory.name : '',
                    'parent_category': scope.parentCategory.parent,
                    'recurring': scope.recurring
                });
            };
        }
    }
});

I want to make sure that budgetCategories from Controller is used by directive.

When I do this I get error as

TypeError: Cannot read property 'push' of undefined
    at Scope.scope.addBudgetCategory (http://localhost:5000/static/app/js/directives/categoryListing.js:28:39)
    at http://localhost:5000/static/app/lib/angular/angular.js:10672:29
    at http://localhost:5000/static/app/lib/angular/angular.js:18763:37
    at Scope.$eval (http://localhost:5000/static/app/lib/angular/angular.js:12533:44)
    at Scope.$apply (http://localhost:5000/static/app/lib/angular/angular.js:12631:41)
    at HTMLButtonElement.<anonymous> (http://localhost:5000/static/app/lib/angular/angular.js:18762:39)
    at HTMLButtonElement.x.event.dispatch (http://localhost:5000/static/app/lib/others/jquery-2.0.0.min.js:1321:108)
    at HTMLButtonElement.y.handle (http://localhost:5000/static/app/lib/others/jquery-2.0.0.min.js:1255:106) 

Question

  • What am I missing here?
  • How can I make sure budgetCatgories from Controller is used by my Directive

Thank you

UPDATE

The html looks like

<div class="budgetEdit" category-listing="budget">
</div>

This line...

scope: {
    budgetCategories: '='
},

Creates an isolate scope for the directive, so its scope does not inherit from the parent scope and therefore has no access to budgetCategories . You have a few options...

1) Don't create an isolate scope by removing the scope: { ... } line from the directive definition.

2 ) Pass budgetCategories into the directive...

<div class="budgetEdit" category-listing="budget" budget-categories="budgetCategories"></div>

3) Use $parent to access the parent scope...

scope.$parent.budgetCategories.push({
    'amount': scope.amount,
    'category': scope.subCategory ? scope.subCategory.name : '',
    'parent_category': scope.parentCategory.parent,
    'recurring': scope.recurring
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM