Angular.js yönergesi dinamik şablonuURL


169

routeProviderŞablon gerektiren bir şablonda özel bir etiket var directive. versionNitelik sonra sağ şablona çağrısında kapsam tarafından doldurulur.

<hymn ver="before-{{ week }}-{{ day }}"></hymn>

Hangi hafta ve güne bağlı olarak ilacın birden fazla versiyonu vardır. Direktifi doğru .htmlkısmı doldurmak için kullanmayı düşünüyordum . Değişken templateUrl. Tarafından okunmuyor .

emanuel.directive('hymn', function() {
    var contentUrl;
    return {
        restrict: 'E',
        link: function(scope, element, attrs) {
            // concatenating the directory to the ver attr to select the correct excerpt for the day
            contentUrl = 'content/excerpts/hymn-' + attrs.ver + '.html';
        },
        // passing in contentUrl variable
        templateUrl: contentUrl
    }
});

Alıntılar dizininde etiketli birden çok dosya var before-1-monday.html , before-2-tuesday.html...



AngularJS 1.5+ kullanıyorsanız bu zarif çözümü kontrol edin: stackoverflow.com/a/41743424/1274852
hkong

Yanıtlar:


184

ng-includeDirektifi kullanabilirsiniz .

Bunun gibi bir şey deneyin:

emanuel.directive('hymn', function() {
   return {
       restrict: 'E',
       link: function(scope, element, attrs) {
           scope.getContentUrl = function() {
                return 'content/excerpts/hymn-' + attrs.ver + '.html';
           }
       },
       template: '<div ng-include="getContentUrl()"></div>'
   }
});

UPD. izlemek için veröznitelik

emanuel.directive('hymn', function() {
   return {
       restrict: 'E',
       link: function(scope, element, attrs) {
           scope.contentUrl = 'content/excerpts/hymn-' + attrs.ver + '.html';
           attrs.$observe("ver",function(v){
               scope.contentUrl = 'content/excerpts/hymn-' + v + '.html';
           });
       },
       template: '<div ng-include="contentUrl"></div>'
   }
});

1
Harika çözümü. Birden çok örneği işleyebileceğini yazmanın bir yolu var mı? Şu anda, kapsam ayarlandıktan sonra yeni attrs.ver öğesini tanımıyor.
Alen Giliana

1
Yani veröznitelik değişikliklerini izlemek ve yönergeyi yeniden göndermek mi istiyorsunuz ?
pgregory

1
Açıklama için teşekkür ederim. Yönergeyi upd. Olarak yayınlanan şekilde bildirirseniz, birden fazla kullanırken kullanım durumunuz <hymn ...>iyi çalışmalıdır. Ya da belki de jsfilddle'da bir prototip oluşturma zamanı ?
pgregory

1
Merhaba @AlenGiliana, ben ve take a look at your site, and changed [JSFiddle](http://jsfiddle.net/JQgG5/6/). All you need is kapsam: {} `direktif bildirimi - kapsam izolasyonu . Ayrıca açısal son sürümünü kullanmanızı şiddetle tavsiye ederim. <script type="text/ng-template" id="...">- html sayfalarına yerel bir alternatiftir
pgregory

1
Açısal 1.2.1'i kullanmak istiyor musunuz? Bu arada yardım için teşekkürler, bu öğrenme eğrisi çılgınca :)
Alen Giliana

313
emanuel.directive('hymn', function() {
   return {
       restrict: 'E',
       link: function(scope, element, attrs) {
           // some ode
       },
       templateUrl: function(elem,attrs) {
           return attrs.templateUrl || 'some/path/default.html'
       }
   }
});

Böylece biçimlendirme yoluyla templateUrl sağlayabilirsiniz

<hymn template-url="contentUrl"><hymn>

Şimdi contentUrl özelliğinin dinamik olarak oluşturulan yolla doldurulmasına dikkat edin .


4
Güzel, ama ... templateUrl işlevinden kapsam niteliklerine erişebilir miyim? TemplateUrl bir kapsam değerine bağlıdır, ancak buna erişemiyorum :(
josec89

1
Çözüm bulduğuna sevindim. Denetleyici ayarlanmadığı sürece yönergelerin bir parçasını gerektirmedikçe yönergesinin ebeveynine bağımlı olmasını tavsiye ETMEM
Andrej Kaurin

11
En sonunda! Tam aradığım şey! Bir templateUrl işlevinden elem ve attr'lere erişimim olduğunu fark etmedim. TEŞEKKÜRLER!
coryvb123

7
templateUrl her yönerge için bir kez çağrılır, her yönerge örneği başlatma sırasında çağrılmaz, dikkatli olun !!! Açısal olsa da bir hata olabilir ...
Lu4

2
Henüz kontrol etmedim ama son bulgularıma göre, muhtemelen bahsetmeye değer once per $compile phase. Başka bir deyişle ng-repeat, direktifinizle birlikte kullanırsanız ve belirli bir ng-repeatöğe bağlamına göre ayrı bir şablon ayarlamak isterseniz , çalışmaz, çünkü $compileaşama gerçek olmadan önce direktifinizden geçer ng-repeat. Yani bu anlamda bir kez deniyor ...
Lu4

6

@Pgregory sayesinde, satır içi düzenleme için bu yönergeyi kullanarak sorunumu çözebilirim

.directive("superEdit", function($compile){
    return{
        link: function(scope, element, attrs){
            var colName = attrs["superEdit"];
            alert(colName);

            scope.getContentUrl = function() {
                if (colName == 'Something') {
                    return 'app/correction/templates/lov-edit.html';
                }else {
                    return 'app/correction/templates/simple-edit.html';
                }
            }

            var template = '<div ng-include="getContentUrl()"></div>';

            var linkFn = $compile(template);
            var content = linkFn(scope);
            element.append(content);
        }
    }
})


2

Aynı sorunu yaşadım ve diğerlerinden biraz farklı bir şekilde çözdüm. Açısal 1.4.4 kullanıyorum.

Benim durumumda, bir CSS Bootstrap paneli oluşturan bir kabuk şablon var:

<div class="class-container panel panel-info">
    <div class="panel-heading">
        <h3 class="panel-title">{{title}} </h3>
    </div>
    <div class="panel-body">
        <sp-panel-body panelbodytpl="{{panelbodytpl}}"></sp-panel-body>
    </div>
</div>

Rotaya bağlı olarak panel gövdesi şablonlarını dahil etmek istiyorum.

    angular.module('MyApp')
    .directive('spPanelBody', ['$compile', function($compile){
        return {
            restrict        : 'E',
            scope : true,
            link: function (scope, element, attrs) {
                scope.data = angular.fromJson(scope.data);
                element.append($compile('<ng-include src="\'' + scope.panelbodytpl + '\'"></ng-include>')(scope));
            }
        }
    }]);

Sonra rota olduğunda aşağıdaki şablonu dahil #/students:

<div class="students-wrapper">
    <div ng-controller="StudentsIndexController as studentCtrl" class="row">
        <div ng-repeat="student in studentCtrl.students" class="col-sm-6 col-md-4 col-lg-3">
            <sp-panel 
            title="{{student.firstName}} {{student.middleName}} {{student.lastName}}"
            panelbodytpl="{{'/student/panel-body.html'}}"
            data="{{student}}"
            ></sp-panel>
        </div>
    </div>
</div>

Panel-body.html şablonu aşağıdaki gibidir:

Date of Birth: {{data.dob * 1000 | date : 'dd MMM yyyy'}}

Birisinin gitmek istediği durumda örnek veriler:

var student = {
    'id'            : 1,
    'firstName'     : 'John',
    'middleName'    : '',
    'lastName'      : 'Smith',
    'dob'           : 1130799600,
    'current-class' : 5
}

0

Bununla ilgili bir örneğim var.

<!DOCTYPE html>
<html ng-app="app">

  <head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  </head>

  <body>
    <div class="container-fluid body-content" ng-controller="formView">
        <div class="row">
            <div class="col-md-12">
                <h4>Register Form</h4>
                <form class="form-horizontal" ng-submit="" name="f" novalidate>
                    <div ng-repeat="item in elements" class="form-group">
                        <label>{{item.Label}}</label>
                        <element type="{{item.Type}}" model="item"></element>
                    </div>
                    <input ng-show="f.$valid" type="submit" id="submit" value="Submit" class="" />
                </form>
            </div>
        </div>
    </div>
    <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
    <script src="app.js"></script>
  </body>

</html>

angular.module('app', [])
    .controller('formView', function ($scope) {
        $scope.elements = [{
            "Id":1,
            "Type":"textbox",
            "FormId":24,
            "Label":"Name",
            "PlaceHolder":"Place Holder Text",
            "Max":20,
            "Required":false,
            "Options":null,
            "SelectedOption":null
          },
          {
            "Id":2,
            "Type":"textarea",
            "FormId":24,
            "Label":"AD2",
            "PlaceHolder":"Place Holder Text",
            "Max":20,
            "Required":true,
            "Options":null,
            "SelectedOption":null
        }];
    })
    .directive('element', function () {
        return {
            restrict: 'E',
            link: function (scope, element, attrs) {
                scope.contentUrl = attrs.type + '.html';
                attrs.$observe("ver", function (v) {
                    scope.contentUrl = v + '.html';
                });
            },
            template: '<div ng-include="contentUrl"></div>'
        }
    })
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.