angularjs对一个元素的两个指令

时间:2013-12-09 12:26:12

标签: javascript angularjs angularjs-directive

我有两个指令:

// 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;
        }
      });
    }
  };
});

// 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;
        }
      });
    }
  };
});

和此输入(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">

我收到此错误:

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

我做错了什么?

如果我从html中删除了clean-me属性,那就可以了。

由于

3 个答案:

答案 0 :(得分:8)

这里没有真正需要隔离的范围。使用&#34;正常&#34;指令范围和指令将只从父节点继承,如下所示:

// 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;
        }
      });
    }
  };
});

如果你已经知道继承如何工作,请忽略此部分,只需添加完整性:

请注意,我使用的是[attrs.focusMe] .value,而不仅仅是[attrs.focusMe]。原因是继承如何在javascript中工作。这些指令是子范围,因此如果您尝试执行范围[attrs.focusMe] = false ,您将在指令范围内设置一个局部变量,即您不会影响父范围(控制器在哪里使用)。但是,如果您在父作用域中创建一个对象(无论它是什么),然后更改该对象上的值,那么它将设置一个局部变量,而是更新父对象。所以:

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

如果你想要一个深度指南,这里有一个关于继承的好答案:What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

答案 1 :(得分:5)

您有两个指令要求在同一元素上使用隔离范围,这是不允许的。

这是不允许的原因是因为如果你在指令中有一些模板{{...}}代码,那么它将不清楚应该从哪个范围取值。

考虑使用attribute.$observe来观看cleanMefocusMe属性并对其进行操作,而不是隔离范围。

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

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;
        }
      });
    }
  };
});

答案 2 :(得分:1)

我最终找到了解决方案:)

// 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;
        }
      });
    }
  };
});

在html usersFocusInput和usersCleanInput是范围内的参数,我使用scope [attributes.focusMe]获取此参数并将其更改为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">