Angular-Meteor - 如何在基于包的设计中包含ng模板?

时间:2022-03-27 17:58:59

I have an Angular-Meteor application working. I would like to package Angular templates and associated controller into a Meteor package, and inject these templates into my main application by adding that package.

我有一个Angular-Meteor应用程序正在运行。我想将Angular模板和关联的控制器打包到Meteor包中,并通过添加该包将这些模板注入我的主应用程序。

What is best approach?

什么是最好的方法?

Update 2015-08-26 - I figured out how to add a template, documented below. But how to have a Meteor package inject the template's Angular controller into the base application?

更新2015-08-26 - 我想出了如何添加模板,如下所示。但是如何让Meteor包将模板的Angular控制器注入基础应用程序?

A key tie-in is Angular UI-router.

关键的搭配是Angular UI-router。

I have a base application that includes my package named packageprefix:packagename. Inside this package I have my code in the root of the package folder: myPackagedPage.ng.html - the Angular HTML template myPackagedPage.js - the associated Angular controller

我有一个基本应用程序,其中包含名为packageprefix:packagename的包。在这个包中,我的代码位于包文件夹的根目录中:myPackagedPage.ng.html - Angular HTML模板myPackagedPage.js - 关联的Angular控制器

From my main application, I tried creating a route to my Angular template like so:

从我的主应用程序,我尝试创建一个到我的Angular模板的路由,如下所示:

angular.module('parentModule',[
    'angular-meteor',
    'ui.router',
    'angularify.semantic.sidebar'
])

.config(['$urlRouterProvider', '$stateProvider', '$locationProvider',
function($urlRouterProvider, $stateProvider, $locationProvider){
    console.log("app.js config!");
    $locationProvider.html5Mode(true);

    $stateProvider
        .state('home', {
            url: '/',
            templateUrl: 'client/views/home/home.ng.html',
            controller: 'HomeCtrl'
        })

        .state('myPackagedPage', {
            url: '/myPackagedPage',
            templateUrl: 'packageprefix_packagename/myPackagedPage.ng.html',
            controller: 'MyPackagedPageCtrl'
        })
    ;

    $urlRouterProvider.otherwise('/');

}])

The application successfully finds the myPackagedPage.ng.html file and renders it. But how to add the controller?

应用程序成功找到myPackagedPage.ng.html文件并呈现它。但是如何添加控制器?

I tried adding this in my package but the controller functions does not get called.

我尝试在我的包中添加它,但控制器函数不会被调用。

console.log("myPackagedPage.js loaded");
angular.module('parentModule')

.controller('MyPackagedPageCtrl', ['$scope',
    function($scope){
        console.log("MyPackagedPageCtrl");
    }])
;

I get an error:

我收到一个错误:

Argument 'MyPackagedPageCtrl' is not a function, got undefined

1 个解决方案

#1


4  

I have this working now. Here is the approach that works for me, to inject an Angular Controller + template in a Meteor package, into the containing application.

我现在有这个工作。这个方法适用于我,将Meular包中的Angular Controller +模板注入到包含的应用程序中。

In my package.js, I have this

在我的package.js中,我有这个

Package.onUse(function(api) {
    api.versionsFrom('1.1.0.3');
    api.use('angular:angular@1.4.4', 'client');
    api.use("urigo:angular@0.9.3", 'client');
    api.use("session@1.1.0", 'client');

    //api.use('angularui:angular-ui-router@0.2.15', 'client');
    api.addFiles('interests.js', 'client');
    api.addFiles('interests.ng.html', 'client');

    api.export("InterestsCtrl", "client")
});

Note you must export your controller, so that the parent application may access it.

请注意,您必须导出控制器,以便父应用程序可以访问它。

In my package, called ramshackle:bigd-interests, I have these files at the root level: package.js, interests.ng.html, and interests.js. interests.js injects the Angular controller, the Anguilar UI-router route to the template, and a sidebar link into the parent application. It accomplishes this by using the Meteor Session. I played with other means of doing this but Session was the only thing that worked. Just be careful to properly scope your session variable names.

在我的包中,名为ramshackle:bigd-interests,我在根级别拥有这些文件:package.js,interests.ng.html和interests.js。 interests.js将Angular控制器,Anguilar UI路由器路由注入模板,以及侧栏链接到父应用程序。它通过使用Meteor Session实现了这一点。我玩过其他方式,但Session是唯一有效的方法。请注意正确确定会话变量名称的范围。

//add controllers
var controllers = Session.get("BIGD.controllers");
if (!controllers) controllers = {};

var interestsCtrlSpec = "'$scope', InterestsCtrl";

InterestsCtrl = function($scope){
    console.log("InterestsCtrl running");
};
controllers.InterestsCtrl = interestsCtrlSpec;
Session.set("BIGD.controllers", controllers);

//add routes
var routes = Session.get("BIGD.routes");
if (!routes) routes = {};
routes.interests = {
    url: '/interests',
    templateUrl: 'ramshackle_bigd-interests_interests.ng.html',
    controller: 'InterestsCtrl'
};
Session.set("BIGD.routes", routes);

//add sidebar links
//the key determines sorting order
var sidebar = Session.get("BIGD.sidebar");
if (!sidebar) sidebar = {};
sidebar["interests"] = {
    url: '/interests',
    templateUrl: 'ramshackle_bigd-interests_interests.ng.html',
    controller: 'InterestsCtrl',
    rank: 5
};
Session.set("BIGD.sidebar", sidebar);

var interestsItem = {label: 'Interests', link: '/interests', icon: "rocket"};

In my parent application's app.js , I dynamically loaded the controllers and routes from the session like this:

在我的父应用程序的app.js中,我动态加载了会话中的控制器和路由,如下所示:

angular.module('bigdam',[
    'angular-meteor',
    'ui.router',
    'angularify.semantic.sidebar',
    'nvd3',
    'leaflet-directive',
    'ui.router.history'
])

    .config(['$urlRouterProvider', '$stateProvider', '$locationProvider',
    function($urlRouterProvider, $stateProvider, $locationProvider){
        //console.log("app.js config!");
        $locationProvider.html5Mode(true);

        //add a static state
        $stateProvider
            .state('home', {
                url: '/',
                templateUrl: 'client/views/home/home.ng.html',
                controller: 'HomeCtrl'
            });

        //add the dynamic routes/states from other Meteor packages
        for (var stateId in routes) {
            var route = routes[stateId];
            $stateProvider
                .state(stateId, route);
        }

        $urlRouterProvider.otherwise('/');
    }])
;

//Declare the controllers from plugins
for (var controllerId in controllers) {
    var controllerSpec = controllers[controllerId];
    var controllerSpecArray = eval("[" + controllerSpec + "]")
    angular.module('bigdam').controller(controllerId, controllerSpecArray);
}

So now, when I create a new Meteor package, and follow the convention described above, its controllers, routes, and sidebar links get loaded into the main application.

所以现在,当我创建一个新的Meteor软件包并遵循上述约定时,其控制器,路由和侧边栏链接将加载到主应用程序中。

#1


4  

I have this working now. Here is the approach that works for me, to inject an Angular Controller + template in a Meteor package, into the containing application.

我现在有这个工作。这个方法适用于我,将Meular包中的Angular Controller +模板注入到包含的应用程序中。

In my package.js, I have this

在我的package.js中,我有这个

Package.onUse(function(api) {
    api.versionsFrom('1.1.0.3');
    api.use('angular:angular@1.4.4', 'client');
    api.use("urigo:angular@0.9.3", 'client');
    api.use("session@1.1.0", 'client');

    //api.use('angularui:angular-ui-router@0.2.15', 'client');
    api.addFiles('interests.js', 'client');
    api.addFiles('interests.ng.html', 'client');

    api.export("InterestsCtrl", "client")
});

Note you must export your controller, so that the parent application may access it.

请注意,您必须导出控制器,以便父应用程序可以访问它。

In my package, called ramshackle:bigd-interests, I have these files at the root level: package.js, interests.ng.html, and interests.js. interests.js injects the Angular controller, the Anguilar UI-router route to the template, and a sidebar link into the parent application. It accomplishes this by using the Meteor Session. I played with other means of doing this but Session was the only thing that worked. Just be careful to properly scope your session variable names.

在我的包中,名为ramshackle:bigd-interests,我在根级别拥有这些文件:package.js,interests.ng.html和interests.js。 interests.js将Angular控制器,Anguilar UI路由器路由注入模板,以及侧栏链接到父应用程序。它通过使用Meteor Session实现了这一点。我玩过其他方式,但Session是唯一有效的方法。请注意正确确定会话变量名称的范围。

//add controllers
var controllers = Session.get("BIGD.controllers");
if (!controllers) controllers = {};

var interestsCtrlSpec = "'$scope', InterestsCtrl";

InterestsCtrl = function($scope){
    console.log("InterestsCtrl running");
};
controllers.InterestsCtrl = interestsCtrlSpec;
Session.set("BIGD.controllers", controllers);

//add routes
var routes = Session.get("BIGD.routes");
if (!routes) routes = {};
routes.interests = {
    url: '/interests',
    templateUrl: 'ramshackle_bigd-interests_interests.ng.html',
    controller: 'InterestsCtrl'
};
Session.set("BIGD.routes", routes);

//add sidebar links
//the key determines sorting order
var sidebar = Session.get("BIGD.sidebar");
if (!sidebar) sidebar = {};
sidebar["interests"] = {
    url: '/interests',
    templateUrl: 'ramshackle_bigd-interests_interests.ng.html',
    controller: 'InterestsCtrl',
    rank: 5
};
Session.set("BIGD.sidebar", sidebar);

var interestsItem = {label: 'Interests', link: '/interests', icon: "rocket"};

In my parent application's app.js , I dynamically loaded the controllers and routes from the session like this:

在我的父应用程序的app.js中,我动态加载了会话中的控制器和路由,如下所示:

angular.module('bigdam',[
    'angular-meteor',
    'ui.router',
    'angularify.semantic.sidebar',
    'nvd3',
    'leaflet-directive',
    'ui.router.history'
])

    .config(['$urlRouterProvider', '$stateProvider', '$locationProvider',
    function($urlRouterProvider, $stateProvider, $locationProvider){
        //console.log("app.js config!");
        $locationProvider.html5Mode(true);

        //add a static state
        $stateProvider
            .state('home', {
                url: '/',
                templateUrl: 'client/views/home/home.ng.html',
                controller: 'HomeCtrl'
            });

        //add the dynamic routes/states from other Meteor packages
        for (var stateId in routes) {
            var route = routes[stateId];
            $stateProvider
                .state(stateId, route);
        }

        $urlRouterProvider.otherwise('/');
    }])
;

//Declare the controllers from plugins
for (var controllerId in controllers) {
    var controllerSpec = controllers[controllerId];
    var controllerSpecArray = eval("[" + controllerSpec + "]")
    angular.module('bigdam').controller(controllerId, controllerSpecArray);
}

So now, when I create a new Meteor package, and follow the convention described above, its controllers, routes, and sidebar links get loaded into the main application.

所以现在,当我创建一个新的Meteor软件包并遵循上述约定时,其控制器,路由和侧边栏链接将加载到主应用程序中。