var tpl = '<button ng-click="submitForm()" submit-form>' + 'Submit'+ '</button>' // 这两个方法都不work $scope.submitForm = function () {} angular.module('xxx', []).directive('submitForm')
感謝回答!
沒時間寫例子佐證了,就簡單說一下我的理解,希望對你有用。
正常情況(即非動態插入 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 就是一個空數組(初始狀態),所以一開始這裡fragments 就是一个空数组(初始状态),所以一开始这里 ng-repeat 不会有任何作用,然后你写一个方法来触发动态插入的动作,把一个类似 { text: 'Submit' } 这样的对象 push 到这个空数组中,ng-repeat 就会“帮”你把 DOM 对象插入了,并且 ng-repeat 本身就会重新 compile 内涵的 DOM 对象,因此 ng-click 不會有任何作用,然後你寫一個方法來觸發動態插入的動作,把一個類似{ text: 'Submit' } 這樣的物件push 到這個空數組中,
fragments
{ text: 'Submit' }
push
本身就會重新compile 內涵的DOM對象,因此submit-form 指令,因为没有必要。如果你要把它写成指令,那么你应该学习 ng-repeat 的方法,简单的说就是监视一个 expression(比如 item in items),当 items 會如你所願的生效。
submit-form
item in items
items
沒時間寫例子佐證了,就簡單說一下我的理解,希望對你有用。
正常情況(即非動態插入 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
指令,舉個例子:這裡的
就會「幫」你把DOM 物件插入了,而且fragments
就是一個空數組(初始狀態),所以一開始這裡fragments
就是一个空数组(初始状态),所以一开始这里ng-repeat
不会有任何作用,然后你写一个方法来触发动态插入的动作,把一个类似{ text: 'Submit' }
这样的对象push
到这个空数组中,ng-repeat
就会“帮”你把 DOM 对象插入了,并且ng-repeat
本身就会重新 compile 内涵的 DOM 对象,因此ng-click
不會有任何作用,然後你寫一個方法來觸發動態插入的動作,把一個類似{ text: 'Submit' }
這樣的物件push
到這個空數組中,本身就會重新compile 內涵的DOM對象,因此
🎜以上兩個例子裡我都去掉了你的submit-form
指令,因为没有必要。如果你要把它写成指令,那么你应该学习ng-repeat
的方法,简单的说就是监视一个 expression(比如item in items
),当items
會如你所願的生效。submit-form
指令,因為沒有必要。如果你要把它寫成指令,那麼你應該學習🎜 的方法,簡單的說就是監視一個expression(比如item in items
),當items
變化的時候,重新compile 內涵的HTML 模版。具體的程式碼你可以去找,angular 是開源的。 🎜