最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - angularjs two directives on one element - Stack Overflow

programmeradmin1浏览0评论

I have two directives:

// Generated by CoffeeScript 1.6.3
app.directive("focusMe", function() {
  return {
    scope: {
      focus: "=focusMe"
    },
    link: function(scope, element) {
      return scope.$watch("focus", function(value) {
        if (value === true) {
          element[0].focus();
          return scope.focus = false;
        }
      });
    }
  };
});

and:

// Generated by CoffeeScript 1.6.3
app.directive("cleanMe", function() {
  return {
    scope: {
      clean: "=cleanMe"
    },
    link: function(scope, element) {
      return scope.$watch("clean", function(value) {
        if (value === true) {
          element[0].value = "";
          return scope.clean = false;
        }
      });
    }
  };
});

and this input (angularUI):

<input type="text" ng-model="addUserSelected" typeahead="emp.value for emp in allUsers | filter:$viewValue | limitTo:5" typeahead-editable="false" typeahead-on-select="addLine($item.id)" focus-me="usersFocusInput" clean-me="usersCleanInput">

I get this error:

Error: [$compile:multidir] .2.3/$compile/multidir?p0=cleanMe&p1=focusMe&p…2%20focus-me%3D%22usersFocusInput%22%20clean-me%3D%22usersCleanInput%22%3E

what do I do wrong?

If I remove the clean-me property from the html it works.

Thanks

I have two directives:

// Generated by CoffeeScript 1.6.3
app.directive("focusMe", function() {
  return {
    scope: {
      focus: "=focusMe"
    },
    link: function(scope, element) {
      return scope.$watch("focus", function(value) {
        if (value === true) {
          element[0].focus();
          return scope.focus = false;
        }
      });
    }
  };
});

and:

// Generated by CoffeeScript 1.6.3
app.directive("cleanMe", function() {
  return {
    scope: {
      clean: "=cleanMe"
    },
    link: function(scope, element) {
      return scope.$watch("clean", function(value) {
        if (value === true) {
          element[0].value = "";
          return scope.clean = false;
        }
      });
    }
  };
});

and this input (angularUI):

<input type="text" ng-model="addUserSelected" typeahead="emp.value for emp in allUsers | filter:$viewValue | limitTo:5" typeahead-editable="false" typeahead-on-select="addLine($item.id)" focus-me="usersFocusInput" clean-me="usersCleanInput">

I get this error:

Error: [$compile:multidir] http://errors.angularjs.org/1.2.3/$compile/multidir?p0=cleanMe&p1=focusMe&p…2%20focus-me%3D%22usersFocusInput%22%20clean-me%3D%22usersCleanInput%22%3E

what do I do wrong?

If I remove the clean-me property from the html it works.

Thanks

Share Improve this question asked Dec 9, 2013 at 12:26 NoampzNoampz 1,2053 gold badges12 silver badges19 bronze badges 2
  • why aren't you just reseting model that ng-model is bound to? I suspect you don't need cleanMe directive – charlietfl Commented Dec 9, 2013 at 13:22
  • cleanMe is no the point, it can be any 2 (or more) directives. clean-me and focus-me is just for the example. – Noampz Commented Dec 9, 2013 at 13:29
Add a comment  | 

3 Answers 3

Reset to default 8

There is no real need for isolated scopes here. Use a "normal" directive scope and the directive will just inherit from the parent, like this:

// Generated by CoffeeScript 1.6.3
app.directive("focusMe", function() {
  return {
    link: function(scope, element, attrs) {
      return scope.$watch(attrs.focusMe, function(focusMe) {
        if (focusMe.value === true) {
          element[0].focus();
          return scope[attrs.focusMe].value = false;
        }
      });
    }
  };
});

// Generated by CoffeeScript 1.6.3
app.directive("cleanMe", function() {
  return {
    link: function(scope, element, attrs) {
      return scope.$watch(attrs.cleanMe, function(cleanMe) {
        if (cleanMe.value === true) {
          element[0].value = "";
          return scope[attrs.cleanMe].value = false;
        }
      });
    }
  };
});

Ignore this part if you already know how inheritance works, just adding for completeness:

Note that I am using the [attrs.focusMe].value, not just [attrs.focusMe]. The reason is how inheritance works in javascript. These directives are child scopes, so if you try to do scope[attrs.focusMe] = false you will set a local variable in the scope of the directive, i.e. you will not affect the parent scope (the controller where it is used). However, if you make the focusMe model (whatever it is) an object in the parent scope and then change a value on that object, then it will not set a local variable, it will instead update the parent. So:

scope[attrs.focusMe] = false; // Sets a local variable, does not affect the parent
scope[attrs.focusMe].value = false; // Updates focusMe on the parent

Here is a good answer about inheritance if you want an in depth guide: What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

You have two directives which require isolated scope on the same element which is not allowed.

The reason this is not allowed is because if you have some template {{...}} code inside the directive, then it will be unclear which scope it should take its values from.

Consider instead of isolating scope, using attribute.$observe to watch the cleanMe and focusMe properties and acting on those.

app.directive("focusMe", function() {
  return {
    link: function(scope, element, attributes) {
      attributes.$observe("focusMe", function(value) {
        if (value === true) {
          element[0].focus();
          scope.focus = false;
        }
      });
    }
  };
});

and:

app.directive("cleanMe", function() {
  return {
    link: function(scope, element, attributes) {
      attributes.$observe("cleanMe", function(value) {
        if (value === true) {
          element[0].value = "";
          return scope.clean = false;
        }
      });
    }
  };
});

I found the solution finally :)

// Generated by CoffeeScript 1.6.3
app.directive("focusMe", function() {
  return {
    link: function(scope, element, attributes) {
      return scope.$watch(attributes.focusMe, function(value) {
        if (scope[value] === true) {
          element[0].focus();
          return scope[attributes.focusMe] = false;
        }
      });
    }
  };
});

// Generated by CoffeeScript 1.6.3
app.directive("cleanMe", function() {
  return {
    link: function(scope, element, attributes) {
      return scope.$watch(attributes.cleanMe, function(value) {
        if (value === true) {
          element[0].value = "";
          return scope[attributes.cleanMe] = false;
        }
      });
    }
  };
});

In the html usersFocusInput and usersCleanInput are parameters in the scope that is wht I use scope[attributes.focusMe] to get this parameter and change him to false.

<input type="text" ng-model="addUserSelected" typeahead="emp.value for emp in allUsers | filter:$viewValue | limitTo:5" typeahead-editable="false" typeahead-on-select="addLine($item.id)" focus-me="usersFocusInput" clean-me="usersCleanInput">
发布评论

评论列表(0)

  1. 暂无评论