0

Here is a non-functioning Plunkr with the relevant code: http://plnkr.co/edit/cM67vJaL0gjma0SoPbK2?p=info

Why does the "pullThirdPartyCollection.html" template have a different scope than the pullThirdPartyCollection directive's link function? I have to use ng-model="$parent.$parent.bggUsername" to make sure two way binding happens correctly. Otherwise, scope.bggUsername is null in the link function's scope.pullCollection function.

If I set an initial value in the link function: scope.bggUsername = 'test', that initial value will display on the screen. Even when I change the value in the input box, and I have an output value {{bggUsername} right next to it, that value changes too. However, when I click the search button and the pullCollection function, inside the link function is called, the scope inside the link function does not have the value I expect for bggUsername.

Also, the pullThirdPartyCollection link function's scope's $id is 20. When I print the value of $id in the template pullThirdPartyCollection.html.js, the value of $id is 33. That is how I figured out I could change the link functions bggUsername by calling $parent.$parent.bggUsername in the template. Still, it does not make sense why the template and the link function have two different scopes. Any ideas what I am I doing wrong?

Here is some of the basic setup

<div paginated-search query="query" total-items="totalItems" current-page="currentPage" items-per-page="itemsPerPage" search-on-load="searchOnLoad" urls="urls" select-item="selectItem(item)" get-search-types="getSearchTypes()" show-search-types="showSearchTypes" selected-search-type="selectedSearchType" edit-item="editItem(e,id)" search-button-id="search-items-button">
                    <div pull-third-party-collection ></div>
</div>

The pullThirdPartyCollection directive:

angular.module('directives.pullThirdPartyCollection', [])
    .directive('pullThirdPartyCollection', function($q, urls, KeyCloakService) {
        return {
            require: '^paginatedSearch',
            restrict: 'EAC',
            templateUrl: 'pullThirdPartyCollection.html',
            scope:{

        },
        link: function postLink(scope, element, attrs, paginatedSearchCtrl) {

            scope.pullCollection = function(e) {

                var deferred = $q.defer();
                $(e.currentTarget).button('loading');
                KeyCloakService.makeRequest(urls.collectionserviceurl + '/pulldata/bgg?username=' + scope.bggUsername + '&collectiontype=trade&urltype=all&subject=' + KeyCloakService.auth.subject,
                    null,
                    function(data) {
                        $(e.currentTarget).button('reset');
                        scope.pulled = true;
                        paginatedSearchCtrl.searchItems();
                        deferred.resolve();
                    },
                    null,
                    'application/json',
                    'application/json',
                    'GET');
                return deferred.promise;
            };

            scope.toggleAllow = function(){
                scope.allow = !scope.allow;
            };
        }
    };
});
Dean Peterson
  • 467
  • 6
  • 15

1 Answers1

1

An existing entry in stackoverflow led me in the right direction:Two way binding not working in directive with transcluded scope. I knew AngularJS had a tendency to create child scopes for transcluded directives. I just didn't realize it can create different scopes between the template and the link function. The child scope's bggUsername initially receives itsvalue from the parent. After that a shadow copy is created and is no longer kept in synch with the parent. Apparently the solution is to only bind objects. From the documentation: every ng-model should have a "." in it. I changed the bound property from a primitive to an object and the object stays in synch inside the link function. So the solution was to make bggUsername an object and change ng-model="bggUsername" to ng-model="bggUsername.value".

Community
  • 1
  • 1
Dean Peterson
  • 467
  • 6
  • 15