jakethecool1
jakethecool1

Reputation: 85

AngularJS directive data is being overwritten

I have made my own type-ahead directive that auto-populates with some names. I have the same type-ahead on my page in two different modals. One of them needs to get every name while the other one only needs to get some of the names. Which ever type-ahead gets loaded last over writes the first type-ahead's data. So if I load the one that is supposed to get some names first and the one that gets all the names second. Both of them grab all the names.

Any help would be greatly appreciated.

Here is my directive:

templates.directive("referralTypeAhead", function (Referrals,AlertFactory) {
return {
restrict:"EA",
replace: true,
require:'ngModel',
// scope: {everyone: "@"},
template: '<input type="text" typeahead="patient.id as patient.plast + \', \' + patient.pfirst + \' \' + patient.mi for patient in patients | filter:$viewValue | limitTo:8" typeahead-min-length="3" typeahead-editable="false" typeahead-input-formatter="formatLabel($model)" class="form-control" />',
link: function(scope, element, attrs, ngModel) {

        var every = attrs.everyone ? attrs.everyone : "false";
        if (everyone === "false") {
          Referrals.getSomeNames({everyone:every}).$promise.then(function(result) {
            var patients = result;
            for (var i = 0; i < patients.length; ++i) {
              if (!patients[i]['mi']) {
                patients[i]['mi'] = '';
              }
            }
            scope.patients = patients;
          },function(result) {
            AlertFactory.addAlert('warning','ERROR: Unable to load data for the referral-type-ahead');
          });
        }
        else {
          Referrals.getAllNames({everyone:every}).$promise.then(function(result) {
            var patients = result;
            for (var i = 0; i < patients.length; ++i) {
              if (!patients[i]['mi']) {
                patients[i]['mi'] = '';
              }
            }
            scope.patients = patients;
          },function(result) {
            AlertFactory.addAlert('warning','ERROR: Unable to load data for the referral-type-ahead');
          });
        }

        scope.formatLabel = function(model) {
          if (scope.patients) {
            for (var i = 0; i < scope.patients.length; ++i) {
              if (scope.patients[i].id == model) {
                return scope.patients[i].plast + ', ' + scope.patients[i].pfirst + ' ' + scope.patients[i].mi;
              }
            }
          }
        };
     }
   };
});

Here is my html:

<referral-type-ahead everyone="false" ng-model="patient.id"></referral-type-ahead>

<referral-type-ahead everyone='true' ng-model="patient.id"></referral-type-ahead>

I don't understand why the second set of data is overwriting the first set.

Upvotes: 1

Views: 656

Answers (1)

Vinay K
Vinay K

Reputation: 5572

When you are creating re-usable components/widgets/directives create isolateScope.

In your directive definition declare scope: {}

It creates private, unshared scope per usage of that directive.

More on isolateScope from angular documentation.

As the name suggests, the isolate scope of the directive isolates everything except models that you've explicitly added to the scope: {} hash object. This is helpful when building reusable components because it prevents a component from changing your model state except for the models that you explicitly pass in.

Note: Normally, a scope prototypically inherits from its parent. An isolated scope does not. See the "Directive Definition Object - scope" section for more information about isolate scopes.

Best Practice: Use the scope option to create isolate scopes when making components that you want to reuse throughout your app.

Upvotes: 1

Related Questions