2013-12-23 195 views
4

使用angular來構建一個大的應用程序,我有一些常見的控制器方法realy即時做到這一點,但存在一個最好的方式來做到這一點?AngularJS擴展控制器

app.controller('baseController', function($scope, $controller, appFactory) { 
    var $scope.foo = function() { 
     // Do something 
    } 
}); 


app.controller('childController', function($scope, $controller, appFactory) { 

    // Here i extend or something like, the base controller 

    $controller('baseController', {$scope: $scope}); 

    var $scope.bar = function() { 
     // Do a lot of things an then call foo 
     $scope.foo(); 
    } 
}): 

我這樣做,因爲這個方法需要有我的控制器的de $範圍。

+1

通常常見的方法應該進入提供者(服務,工廠,...)。請記住,Angular是圍繞着「在視圖和模型之間進行調解」的瘦控制器設計的。如果你可以給一些更具體的細節,我可能會給你更具體的建議 – KayakDave

+0

請參閱此線程http://stackoverflow.com/questions/16539999/angular-extending-controllers – user2923779

回答

3

我不同意上面的意見,不應該繼承控制器的繼承。有很多情況下,即使您使用共享服務/工廠/提供程序,控制器繼承仍會使代碼保持乾爽。使用@Clever的答案示例,爲什麼要在X個控制器中重複$scope.foo = function() { MyFactory.calculateFoo(); },如果可以將其放入單個基本控制器中。這並不會使控制器變胖,而是將其清理乾淨並保持乾燥。

Misko自己在AngularJS谷歌組中給出了這個example關於控制器繼承的一個可能的實現。我個人使用這個方法我自己,簡單的例子,從叫我的孩子控制器中:

$injector.invoke(MyBaseController, this, { $scope: $scope, alertService: alertService }); 

的,我用控制器繼承,對於大多數我的CRUD的網頁我有一個實現通用創造一個單親控制器的一個例子/更新$範圍函數。這個基礎控制器獲得注入的資源庫服務,用於執行實際的服務器調用等等。爲什麼對於所有的CRUD頁面反覆重複這個問題?

+0

我同意有些情況下,這樣的事情真的你從一個乾燥的角度展示了一個有趣的例子。但是我擔心它可以輕鬆地擺脫瘦控制器的理想。在你的具體例子中,我的問題是服務器調用算作「業務邏輯」嗎?如果是這樣的話,我所看到的Angular團隊的建議是業務邏輯應該進入提供商,而控制器的唯一工作就是將這些結果映射到視圖上。偉大的建築討論! – KayakDave

+0

@KayakDave我也覺得這個話題很有趣。在我的示例中,服務器調用和任何業務邏輯實際上仍然在提供者中實現,基礎控制器只是實現提供者功能和結果在視圖上的通用/共享映射。所以我相信它符合一般建議。 – Beyers

+0

我沒有看到基本控制器的用例。模型和業務邏輯使用相應的存儲庫進行定義。爲什麼控制器甚至會創建/更新$範圍?如果您有重複的組件需要控制器上的某些內容,那麼只需將控制器或指令包含在模板的該部分中即可。 – FlavorScape

1

爲了闡述KayakDave的說法,Angular控制器通常是輕量級的。如果你發現自己在控制器中思考「繼承」,那麼你可能做錯了。將控制器之間共享的公共邏輯提取爲Service/Factory/Provider會更好。例如:

app.Factory('MyFactory', function() { 
    return { 
     calculateFoo: function() { 
      // stuff 
     } 
    }; 

}); 

app.controller('FirstCtrl', function($scope, $controller, MyFactory) { 
    var $scope.foo = function() { 
     MyFactory.calculateFoo(); 
    } 
}); 


app.controller('SecondCtrl', function($scope, $controller, MyFactory) { 

    var $scope.bar = function() { 
     MyFactory.calculateFoo(); 
    } 
}):