簡體   English   中英

角度模型/控制器“層次結構”設置

[英]Angular model/controller “hierarchy” setup

我正在使用ngboilerplate構建一個角度應用程序,該應用程序本質上是我所有網站及其環境的管理面板。 我需要設置一種函數和模型數據的層次結構,以便任何“子”控制器/模型在未設置“父”的情況下都無法工作。 這是我要解釋的細分。

模型->環境(產品,階段,開發),一旦選擇了環境,就可以選擇站點

模型->網站(當前環境中的所有網站),一旦選擇了一個網站,您就可以獲取該網站的數據

模型->網站(網站數據json包含頁面配置值之類的內容)

為此類設置結構的正確方法是什么? 我目前僅對頁面內的每個路由使用單獨的控制器和路由(ui-router)。 我需要確保的主要功能是,如果選擇了某個站點后更改了環境,則該站點的數據將從正確的環境中重新加載。 我想我將使用$ watch來確保嗎? 任何有關最佳做法的建議/技巧都值得贊賞!

更新:這里要澄清一些細節:

我需要“監視”的主要模型是環境模型。 根據設置的環境,我將調整所使用的api網址以及更改顯示名稱。 同樣,它也將加載env的相應站點列表(當前是一個靜態json文件,但它可以是一個api調用)。 這是我問這個問題之前寫的代碼,當我得到SitesCtrl時,我意識到我可能做錯了(或者無論如何都不是最佳選擇)。

Tools.js

angular.module( 'SupportBase.tools', [
  'ui.router',
  'placeholders',
  'ui.bootstrap',
  'SupportBase.tools.sites'
])

.config(function config( $stateProvider ) {
  $stateProvider.state( 'tools', {
    url: '/tools',
    views: {
      "main": {
        controller: 'ToolsCtrl',
        templateUrl: 'tools/tools.tpl.html'
      },
      "sites": {
        controller: 'SitesCtrl',
        templateUrl: 'tools/sites/sites.tpl.html'
      }
    },
    data:{ pageTitle: 'Site Tools' }
  });
})

.controller( 'ToolsCtrl', function ToolCtrl( $scope ) {
  $scope.envModel = '';

});

Tools.tpl.hmtl

    <div class="row">
    <h1 class="page-header">
    Site Tools
    <small>For the lazy and impatient. {or the smart & productive}</small>
  </h1>
</div>
<div class="row">
    <div class="well col-md-5">
        <h4>Current Working Environment:
        <code class="env">{{envModel || 'null'}}</code></h4>
        <div class="btn-group col-md-10 col-md-offset-2">
            <label class="btn btn-primary" ui-sref="tools.sites({env: envModel})" ng-model="envModel" btn-radio="'Production'">Production</label>
            <label class="btn btn-primary" ui-sref="tools.sites({env: envModel})" ng-model="envModel" btn-radio="'Stage'">Stage</label>
            <label class="btn btn-primary" ui-sref="tools.sites({env: envModel})" ng-model="envModel" btn-radio="'QA'">QA</label>
            <label class="btn btn-primary" ui-sref="tools.sites({env: envModel})" ng-model="envModel" btn-radio="'Dev'">Dev</label>
        </div>
    </div>
    <div class="col-md-6" ui-view="sites"></div>
</div>

Sites.js

angular.module('SupportBase.tools.sites', [
    'ui.router',
    'placeholders',
    'ui.bootstrap',
    'SupportBase.tools'
])

.config(function config($stateProvider) {
    $stateProvider.state('tools.sites', {
        url: '/{env:[a-z]{1,10}}/sites',
        views: {
            "sites": {
                controller: 'SitesCtrl',
                templateUrl: 'tools/sites/sites.tpl.html'
            }
        },
        data: {
            pageTitle: 'Site Tools | SupportBase'
        }
    });
})

.controller('SitesCtrl', function SitesCtrl($scope, $stateParams, $http) {
    $scope.env = $stateParams.env.toLowerCase();
    $scope.disabled = $stateParams.env !== '' ? false : true;
    if ($stateParams.env.toLowerCase() === 'production') {
        $http.get('./src/app/sites/sites.json').success(function(data) {
            $scope.sitesModel = data;
        });
    } else {
        $scope.sitesModel = [$stateParams.env, 'something', 'face'];
    }


});

Sites.tpl.html

    <div class="well" collapse="disabled">
    <h1>Site Selector</h1>
    <h2>{{sitesModel}}</h2>
    </div>

仍然對您要執行的操作含糊不清。 以下是一些入門代碼:

.constant('site_configuration', {
    'greeting' : 'Hello User'
});


.factory('environment', function ($window, $q, $http, $log, $rootScope, secondary_service, site_configuration) { 

    // this way your child functions can call each other within the factory
    var environment = {};
    environment.prod = function() {

    };

    environment.dev = function(credentials) {
        secondary_service.login(credentials).then(function(){
            $log.log('hello')
            site_configuration.greeting = 'Hello Dev Environment User!'
        })
    };

    environment.stage = function(credentials) {
    // do something
    }

    return environment;
})


.service('secondary_service', function ($window, $q, $log, $rootScope, $http) {
    var myservice = {};

    secondary_service.login = function() {
        var deferred = $q.defer();
        // some http call
        deferred.resolve(true)

        return deferred.promise;
   };
   return myservice;
})

我不使用ui.router,所以我會很通用,可以根據需要申請。

另外我還沒有測試這個確切的代碼,因此請使用它作為指南。

// setup constants to refer to and change when needed
.constant('site_config', {
    'api_path' : '//prod.example.com',
    'name' : 'Production',
    'collection' : '/production'
});




.controller( 'homepage_controller', function($scope, $location, $log, site_config, environment){

    var load_site = function() {
        $scope.title = site_config.name;
        environment.get().then(function(data){
            $log.log('Do something with this ',data)
        })
    }

    // looking for sandbox.example.com 
    if(window.location.host.indexOf('sandbox') > -1 ) {
        environment.set('prod').then(function(){
            $log.log('sandbox is loaded')
            load_site()
        })

    // looking for qa.example.com 
    } else if (window.location.host.indexOf('qa') > -1) {
        environment.set('qa').then(function(){
            $log.log('qa is loaded')
            load_site()
        })

    // looking for www.example.com 
    } else {
        environment.set('prod').then(function(){
            $log.log('production is loaded')
            load_site()
        })
    }

})





.factory('environment', function ($window, $q, $http, $log, $rootScope, site_config) { 
    var environment = {};

    environment.set = function(type) {
        var deferred = $q.defer();

        if(type == 'sandbox') {
            site_config.api_path = '//sandbox.example.com';
            site_config.name = 'Sandbox';
            site_config.collection = '/development';
            deferred.resolve(true)
        }
        if(type == 'qa') {
            site_config.api_path = '//qa.example.com';
            site_config.name = 'QA';
            site_config.collection = '/qa';
            deferred.resolve(true)
        }
        if(type == 'production') {
            site_config.api_path = '//prod.example.com';
            site_config.name = 'Production';
            site_config.collection = '/production';
            deferred.resolve(true)
        }
        return deferred.promise;
    };

    // just showing this as an example
    environment.get = function() {

        var deferred = $q.defer();
        $http({
            method:'GET',
            url: site_config.api_path+site_config.collection
        })
        .success(function(data) {
            deferred.resolve(data);
        })
        .error(function(status, headers, config) {
            deferred.reject(false);
        });
        return deferred.promise;
    }

    return environment;
})

你看過工廠嗎? 它們本質上是可以用作服務層的單例模式。 每個控制器可以依賴於同一工廠獲取其數據並綁定到該工廠,並且當數據更改時,更改會被通用更新

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM