javascript AngularJS 指令未显示在模板上

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20143566/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 17:51:14  来源:igfitidea点击:

AngularJS directive not showing up on template

javascriptangularjsangularjs-directiveangularjs-scope

提问by Jochen van Wylick

I've got a tiny problem with an angular directive that's now working and I don't know why. I think it's a fairly simple issue that I'm overlooking, maybe you can help me out.

我的角度指令有一个小问题,现在正在工作,我不知道为什么。我认为这是我忽略的一个相当简单的问题,也许你可以帮助我。

Directive is defined like this:

指令定义如下:

angular.module('directives', [])
    .directive('my-directive', function () {
        return {
            restrict: 'AE',
            scope: {
                name: '=name'
            },
            template: '<h1>{{name}}</h1>'
        };
    });

Then index.cshtml:

然后index.cshtml:

<my-directive name="test"></my-directive>

Application.js:

应用程序.js:

var app = angular.module('MyApp', [
    ...,
    'directives'
]);

And here's controllers.js

这是controllers.js

angular.module('controllers', ['apiServices', 'directives'])
    .controller('homecontroller', function($scope, $resource, webApiService, $log, $translate, $localStorage, $sessionStorage) {

Ok confirmed that directives.js is loaded, otherwise application.js nags about 'unknown module'. There are no error messages in the console, the thing just doesn't show. Any ideas?

Ok 确认已加载了directives.js,否则application.js 唠叨“未知模块”。控制台中没有错误消息,只是没有显示。有任何想法吗?



EDIT

编辑

So as pointed out, I changed the directive name to camelCase, but still no luck:

正如所指出的,我将指令名称更改为camelCase,但仍然没有运气:

<my-directive name="John Doe"></my-directive>

And

.directive('myDirective', function () {

But nothing is showing yet.

但还没有显示任何内容。

EDIT

编辑

Problem is that angular expects an object to be passed into the attribute, not a string literal. If you create an object person = { name: 'John' }, pass the person in, then write {{ person.name }} ( assuming we named the attribute person + scope var person too ).

问题是 angular 期望将对象传递给属性,而不是字符串文字。如果您创建一个对象 person = { name: 'John' },将 person 传入,然后写入 {{ person.name }} (假设我们也将属性命名为 person + 范围 var person )。

回答by AlwaysALearner

During normalization, Angular converts -delimited name to camelCase.

规范化期间,Angular 将-分隔名称转换为驼峰命名。

So use camelCase while specifying the directive inside JS:

所以在 JS 中指定指令时使用camelCase:

.directive('myDirective', function () {

Fiddle

Fiddle

回答by Gene

I'm sure you've figured this out already, but if you change your scope definition for name to be

我相信您已经想通了,但是如果您将 name 的范围定义更改为

scope: {
  name: '@'
}

you will then be able to pass a string. The '@' interpolates the attribute while the '=' binds it. Additionally, you don't need to include an attribute name if it is the same as the scope variable.

然后你就可以传递一个字符串。'@' 插入属性,而 '=' 绑定它。此外,如果属性名称与作用域变量相同,则不需要包含属性名称。

回答by Jared Clemence

The problem appears to be in the directive definition. You note in your question that Angular expects an object; this is true for the "=" scope, but not for the "@" scope. In the "@" scope, Angular expects a string only. I have created a snippet below.

问题似乎出在指令定义中。您在问题中注意到 Angular 需要一个对象;这适用于“=”范围,但不适用于“@”范围。在“@”范围内,Angular 只需要一个字符串。我在下面创建了一个片段。

Too many modules

模块太多

Unless you are reusing the directive in multiple applications, do not create a new module for it. Add the directive definition to the module that you created for the application. In my example below, I called the module back by using "angular.module( moduleName )"... When only one argument is used, Angular returns the existing object rather than creating a new one. This is how we can separate the code into many files.

除非您在多个应用程序中重用该指令,否则不要为其创建新模块。将指令定义添加到您为应用程序创建的模块中。在下面的示例中,我通过使用“angular.module(moduleName)”来调用模块......当只使用一个参数时,Angular 返回现有对象而不是创建一个新对象。这就是我们如何将代码分成许多文件。

Things to Note

注意事项

You will notice the following:

您会注意到以下几点:

  1. You do not need to load the module into the app variable. Calling the Singleton each time is actually safer and easier on memory management.
  2. The directive is in camel case, as you have already noted.
  3. I am setting the name attribute to a string value and not an object; this works because of the "@" scope setting.
  4. The div is set to ng-app='MyApp'. This usually is set to the html element, but I did not want to mess with the DOM on Stack Exchange. The ng-app directive can be set on any element, and the directives associated with that module will be applied on all elements that are within that element's scope. Without the ng-app directive, Angular does not know which module to run on the page.
  1. 您不需要将模块加载到 app 变量中。每次调用 Singleton 实际上在内存管理上更安全、更容易。
  2. 正如您已经注意到的,该指令采用驼峰式格式。
  3. 我将 name 属性设置为字符串值而不是对象;这是因为“@”范围设置。
  4. div 设置为 ng-app='MyApp'。这通常设置为 html 元素,但我不想在 Stack Exchange 上弄乱 DOM。ng-app 指令可以设置在任何元素上,与该模块关联的指令将应用于该元素范围内的所有元素。如果没有 ng-app 指令,Angular 不知道在页面上运行哪个模块。

//app.js - this defines the module, it uses two parameters to tell the injector what to do.
angular.module('MyApp',[]);

//directive.js stored elsewhere
//this calls back the module that has been created. It uses one parameter because the injector is no longer needed.
angular.module('MyApp').directive('myDirective', function () {
       return {
         restrict: 'AE',
           scope: {
             name: '@'
         },
         template: '<h1>{{name}}</h1>'
       };
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    
<div ng-app="MyApp">
<h1>Successful Load</h1>
<my-directive name="test"></my-directive>
<p>By applying the directive definition to the MyApp module, the MyApp module knows to activate the directive within this scope. In this form, it does not get injected.</p>
</div>

Using Injection

使用注入

When you have a different module for each and every directive or controller, each one must be injected into the application's module definition. This leaves a lot of room for error. As a best practice, only create a new module when necessary, and make the module a container for a group of related functionality and not a single item.

当每个指令或控制器都有不同的模块时,每个指令或控制器都必须注入应用程序的模块定义中。这给错误留下了很大的空间。作为最佳实践,仅在必要时创建新模块,并使模块成为一组相关功能而不是单个项目的容器。

The code below demonstrates proper injection.

下面的代码演示了正确的注入。

angular.module( "MyApp", ['ReusableDirectives'] );
angular.module( "MyApp" ).directive( "myDirective", function(){
  return {
    restrict: "AE",
    scope: { name: "@" },
    template: "<p>This is the directive I defined in the example above. It uses <u>the same module</u> as my main application, because it is not going to be reused over and over again. In fact, I will need it just for this application, so I don't need to complicate things with a new module.  This directive takes an attribute called 'name' and if it is a string allows me to manipulate the string within my templates scope to do things like this: {{'hello ' + name + '!'}}</p>"
  };
} );
angular.module( "ReusableDirectives", [] );
angular.module( "ReusableDirectives" ).directive("reusableDirective", function(){
  return {
    restrict: "E",
    template: "<p>This is a directive that I intend to use in many, many applications. Because I will reuse it so much, I am putting it in a separate module from my main application, and I will inject this directive. This is the only reason that this directive is not in the same module as the one I defined above.</p>"
  };
} ).directive("reusableDirective2", function(){
  return {
    restrict: "E",
    template: "<p>This is a second directive that I intend to use in multiple applications. I have stored it in a module with the first directive so that I can freely inject it into as many apps as I like.</p>"
  };
} )
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="MyApp">
  <h1>Successful Load</h1>
  <my-directive name="Johnny"></my-directive>
  <p>By applying the directive definition to the MyApp module, the MyApp module knows to activate the directive within this scope. In this form, it does not get injected.</p>
  <h3>Injected Directives</h3>
  <reusable-directive></reusable-directive>
  <reusable-directive2></reusable-directive2>
</div>

Keep it simple. Define your directives on a single module for your application. Once you have that done and working, if you need the directives again in another application, refactor and experiment with injections at that time after you have some more Angular practice under your belt.

把事情简单化。在应用程序的单个模块上定义指令。一旦你完成并工作,如果你在另一个应用程序中再次需要这些指令,在你有更多的 Angular 练习之后,重构并在那个时候尝试注入。

You have a bright future with Angular, keep up the good work!

你在 Angular 有一个光明的未来,继续努力!

回答by Muhammad Reda

Your directive must be camel-cased

你的指令必须是驼峰式的

    .directive('myDirective', function () {

then in your html, your are free whether to call it my-directiveor myDirective

然后在您的 html 中,您可以自由调用它my-directivemyDirective

Both are valid

两者都有效

<my-directive name="test"></my-directive>
<myDirective name="test"></myDirective>

回答by csharpsql

Just to follow up on this, I had to use the following way to get my directive to work.

只是为了跟进这一点,我不得不使用以下方式让我的指令起作用。

<my-directive name="test"></my-directive>