var tpl = '<button ng-click="submitForm()" submit-form>' + 'Submit'+ '</button>' // 这两个方法都不work $scope.submitForm = function () {} angular.module('xxx', []).directive('submitForm')
感谢回答!
それを裏付ける例を書く時間がないので、私の理解を簡単に説明します。
通常の状況 (つまり、DOM オブジェクトを動的に挿入していない状態) では、ng-click のような命令が有効である (つまり、可視スコープに登録されているメソッドはクリック後に呼び出すことができる) のは次のとおりです。 angular はコンパイル段階 (コンパイル段階) で、ホスト DOM オブジェクト (つまり、ng-click ディレクティブが追加された DOM オブジェクト) を現在のスコープにバインドします。 ng-click 这样的指令之所以有效(即点击之后能调用注册在可见作用域里的方法),是因为 angular 在 compiling phase(编译阶段)将宿主 DOM 对象(即加入了 ng-click 指令的 DOM 对象)绑定在当前作用域内了。
ng-click
换言之,当前作用域知道有这个绑定了 ng-click 的 DOM 对象存在,所以 ng-click 才会起作用。
而在你的例子里,HTML 片段是在 compiling phase 后动态插入到 DOM 树中的,即便你写了 ng-click,当前的作用域也不知道这个指令的存在,所以才会无效。
因此,当你动态插入 HTML 片段的时候,要手动调用 $compile 服务并将这个 DOM 对象绑定给当前的作用域(或其他可见作用域,这要看你的应用逻辑了),具体方法如下:
$compile
// 在某一个 controller 中,假设用 jQuery 动态插入一个 HTML 片段…… $('selector').html( $compile( '<button ng-click="submitForm()">' + 'Submit' + '</button>' )(scope) );
注意要先注入 $compile 服务。
另外,这种方式明显太“恶心”,还有一个更好的办法(但是大量动态插入会有性能损耗)就是利用 ng-repeat 指令,举个例子:
ng-repeat
<!-- 在要动态插入的地方…… --> <p class="form-control" ng-repeat="fragment in fragments"> <button ng-click="submitForm()">{{fragment.text}}</button> </p>
这里的 fragments 就是一个空数组(初始状态),所以一开始这里 ng-repeat 不会有任何作用,然后你写一个方法来触发动态插入的动作,把一个类似 { text: 'Submit' } 这样的对象 push 到这个空数组中,ng-repeat 就会“帮”你把 DOM 对象插入了,并且 ng-repeat 本身就会重新 compile 内涵的 DOM 对象,因此 ng-click 会如你所愿的生效。
fragments
{ text: 'Submit' }
push
以上两个例子里我都去掉了你的 submit-form 指令,因为没有必要。如果你要把它写成指令,那么你应该学习 ng-repeat 的方法,简单的说就是监视一个 expression(比如 item in items),当 items
submit-form
item in items
items
それを裏付ける例を書く時間がないので、私の理解を簡単に説明します。
通常の状況 (つまり、DOM オブジェクトを動的に挿入していない状態) では、
ng-click
のような命令が有効である (つまり、可視スコープに登録されているメソッドはクリック後に呼び出すことができる) のは次のとおりです。 angular はコンパイル段階 (コンパイル段階) で、ホスト DOM オブジェクト (つまり、ng-click
ディレクティブが追加された DOM オブジェクト) を現在のスコープにバインドします。ng-click
这样的指令之所以有效(即点击之后能调用注册在可见作用域里的方法),是因为 angular 在 compiling phase(编译阶段)将宿主 DOM 对象(即加入了ng-click
指令的 DOM 对象)绑定在当前作用域内了。换言之,当前作用域知道有这个绑定了
ng-click
的 DOM 对象存在,所以ng-click
才会起作用。而在你的例子里,HTML 片段是在 compiling phase 后动态插入到 DOM 树中的,即便你写了
ng-click
,当前的作用域也不知道这个指令的存在,所以才会无效。因此,当你动态插入 HTML 片段的时候,要手动调用
$compile
服务并将这个 DOM 对象绑定给当前的作用域(或其他可见作用域,这要看你的应用逻辑了),具体方法如下:注意要先注入
$compile
服务。另外,这种方式明显太“恶心”,还有一个更好的办法(但是大量动态插入会有性能损耗)就是利用
ng-repeat
指令,举个例子:这里的
fragments
就是一个空数组(初始状态),所以一开始这里ng-repeat
不会有任何作用,然后你写一个方法来触发动态插入的动作,把一个类似{ text: 'Submit' }
这样的对象push
到这个空数组中,ng-repeat
就会“帮”你把 DOM 对象插入了,并且ng-repeat
本身就会重新 compile 内涵的 DOM 对象,因此ng-click
会如你所愿的生效。以上两个例子里我都去掉了你的
言い換えると、現在のスコープはsubmit-form
指令,因为没有必要。如果你要把它写成指令,那么你应该学习ng-repeat
的方法,简单的说就是监视一个 expression(比如item in items
),当items
ng-click
にバインドされた DOM オブジェクトが存在することを認識しているため、ng-click
は機能します。 🎜 🎜あなたの例では、HTML フラグメントはコンパイル段階の後に DOM ツリーに動的に挿入されます。ng-click
を記述しても、現在のスコープはこのディレクティブの存在を認識しません。無効。 🎜 🎜 したがって、HTML フラグメントを動的に挿入する場合は、$compile
サービスを手動で呼び出して、この DOM オブジェクトを現在のスコープ (または、アプリケーションのロジックに応じて他の表示可能なスコープ) にバインドする必要があります。方法は次のとおりです: 🎜 リーリー 🎜$compile
サービスを最初に挿入する必要があることに注意してください。 🎜 🎜 さらに、この方法は明らかに「不快」すぎます。たとえば、ng-repeat
ディレクティブを使用する、より良い方法があります (ただし、多数の動的挿入によりパフォーマンスが低下します)。 🎜 リーリー 🎜ここでのfragments
は空の配列 (初期状態) であるため、最初はng-repeat
は何の効果も持たず、その後、動的挿入アクションをトリガーするメソッドを作成します。 、{ text: 'Submit' }
のようなオブジェクトをこの空の配列にpush
します。ng-repeat
は "DOM オブジェクトを挿入するのに役立ちます"ng-repeat
自体が基になる DOM オブジェクトを再コンパイルするため、ng-click
は期待どおりに機能します。 🎜 🎜上記の 2 つの例では、submit-form
ディレクティブは必要ないため、削除しました。これを命令として書きたい場合は、ng-repeat
メソッドを学習する必要があります。これは単に式 (item in items
の When items が変更されると、基礎となる HTML テンプレートを再コンパイルします。具体的なコードは見つかります。angular はオープンソースです。 🎜