คุณสามารถแทนที่เทมเพลตเฉพาะใน AngularUI Bootstrap ได้หรือไม่?


88

ฉันอยากรู้ว่ามีวิธีลบล้างเทมเพลตเฉพาะจากไฟล์ ui-bootstrap-tpls หรือไม่ เทมเพลตเริ่มต้นส่วนใหญ่เหมาะกับความต้องการของฉัน แต่มีเทมเพลตที่เฉพาะเจาะจงสองสามรายการที่ฉันต้องการแทนที่โดยไม่ต้องผ่านขั้นตอนทั้งหมดในการคว้าเทมเพลตเริ่มต้นทั้งหมดและเชื่อมต่อกับเวอร์ชันที่ไม่ใช่ tpls


1
ฉันยังพบว่าตัวเองตกแต่ง$modalบริการเพื่อให้สามารถกำหนดค่าได้มากขึ้นโดยที่ (หวังว่า) จะสร้างความปวดหัวในการบำรุงรักษา $provide.decorator('$modal'... ในกรณีของฉันฉันไม่ต้องการแสดงmodalWindowองค์ประกอบ เคย. ฉันไม่ได้ใช้มันและนี่คือสิ่งที่ดีที่สุดที่ฉันสามารถทำได้ ฉันชอบที่จะได้ยินวิธีที่ดีกว่านี้ถ้าใครมี
โบดีน

คำตอบ:


123

ใช่คำสั่งจากhttp://angular-ui.github.io/bootstrapสามารถปรับแต่งได้สูงและง่ายต่อการลบล้างเทมเพลตอย่างใดอย่างหนึ่ง (และยังคงใช้คำสั่งเริ่มต้นสำหรับคำสั่งอื่น ๆ )

ก็เพียงพอแล้วที่จะให้อาหาร$templateCacheไม่ว่าจะป้อนโดยตรง (ตามที่ทำในui-bootstrap-tplsไฟล์) หรือ - อาจง่ายกว่า - แทนที่เทมเพลตโดยใช้<script>คำสั่ง ( doc )

ตัวอย่างที่วางแผนไว้ที่ฉันเปลี่ยนแม่แบบการแจ้งเตือนในการแลกเปลี่ยนxสำหรับการCloseแสดงอยู่ด้านล่าง:

<!doctype html>
<html ng-app="plunker">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
    <script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.4.0.js"></script>
    <script src="example.js"></script>
    <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">

    <script id="template/alert/alert.html" type="text/ng-template">
      <div class='alert' ng-class='type && "alert-" + type'>
          <button ng-show='closeable' type='button' class='close' ng-click='close()'>Close</button>
          <div ng-transclude></div>
      </div>
    </script>
  </head>

  <body>
    <div ng-controller="AlertDemoCtrl">
      <alert ng-repeat="alert in alerts" type="alert.type" close="closeAlert($index)">                     
        {{alert.msg}}
      </alert>
      <button class='btn' ng-click="addAlert()">Add Alert</button>
    </div>
  </body>
</html>

ผู้เล่นสด: http://plnkr.co/edit/gyjVMBxa3fToYTFJtnij?p=preview


19
ฉันชอบคำตอบนี้ ฉันไม่ชอบความจริงที่ว่ามันไม่ได้รวมอยู่ในหน้าเอกสารของ Angular UI และฉันใช้เวลาพอสมควรในการคิดหาวิธีทำอะไรง่ายๆอย่างการแสดงโมดอล
Tri Vuong

2
@BruceBanner เอกสารประกอบและตัวอย่างการทำงานที่มั่นคงเป็นสองความล้มเหลวที่ใหญ่ที่สุดของ Angular UI โครงการนี้ยอดเยี่ยม แต่ต้องการความรักจากนักพัฒนาที่อ่อนโยน
Robin van Baalen

1
@RobinvanBaalen นี่คือคุณลักษณะเชิงมุม -Js (ไม่ใช่เชิงมุม -Ui) ซึ่งได้รับการบันทึกไว้แล้วในเอกสารอย่างเป็นทางการของ js เชิงมุม
vikki

โปรดตรวจสอบคำตอบของ @JcT เกี่ยวกับ $ give.decorator เนื่องจากเป็นวิธี Angular (วิธีที่ดีในกรณีนี้) ในการแทนที่เทมเพลตคำสั่ง และมันค่อนข้างง่าย เพียงแค่การเพิ่ม / การแทนที่เทมเพลตใน $ templateCache ไม่ใช่แนวทางปฏิบัติที่ดีที่สุด
John Bernardsson

@ จอห์นฉันไม่แน่ใจว่าคุณได้สิ่งต่างๆมาจากไหน "นั่นคือวิธีเชิงมุม (วิธีที่ดีในกรณีนี้)" และ "การเพิ่ม / การแทนที่เทมเพลตให้กับ $ templateCache ไม่ใช่แนวทางปฏิบัติที่ดีที่สุด" แต่เป็นหนึ่งในเชิงมุม - ui และผู้ดูแลเชิงมุมฉันมั่นใจได้ว่าไม่มีอะไรผิดปกติกับการลบล้างเทมเพลต เว้นแต่คุณมีปัญหาเฉพาะที่จะแบ่งปัน ...
pkozlowski.opensource

80

การใช้ $provide.decorator

ใช้$provideในการตกแต่งสั่งหลีกเลี่ยงความจำเป็นในการโดยตรงยุ่ง ๆ $templateCacheกับ

ให้สร้าง html เทมเพลตภายนอกของคุณตามปกติโดยใช้ชื่ออะไรก็ได้ที่คุณต้องการแล้วแทนที่คำสั่งที่templateUrlจะชี้ไป

angular.module('plunker', ['ui.bootstrap'])
  .config(['$provide', Decorate]);

  function Decorate($provide) {
    $provide.decorator('alertDirective', function($delegate) {
      var directive = $delegate[0];

      directive.templateUrl = "alertOverride.tpl.html";

      return $delegate;
    });
  }

ส้อมของpkozlowski.opensourceของ plunkr: http://plnkr.co/edit/RE9AvUwEmKmAzem9mfpI?p=preview

(โปรดทราบว่าคุณต้องต่อท้ายคำสั่ง "คำสั่ง" ต่อท้ายชื่อคำสั่งที่คุณต้องการตกแต่งด้านบนเรากำลังตกแต่งalertคำสั่งของ UI Bootstrap ดังนั้นเราจึงใช้ชื่อalertDirectiveนี้)

ในขณะที่คุณมักต้องการทำมากกว่าการลบล้างสิ่งtemplateUrlนี้จึงเป็นจุดเริ่มต้นที่ดีในการขยายคำสั่งเพิ่มเติมเช่นโดยการแทนที่ / ตัดลิงก์หรือฟังก์ชันคอมไพล์ ( เป็นต้น )


9
นี่เป็นวิธีแก้ปัญหาที่ถูกต้องและปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดเชิงมุม คุณไม่ควรใช้สตริงเพื่อสร้าง HTML และไม่ควรรวมไว้ในไฟล์ index.html อย่างชัดเจนที่คุณฉีดสคริปต์ของบุคคลที่สาม ขอบคุณ @JcT!
TommyMac

2
สวัสดีalertDirectiveคีย์เวิร์ดคืออะไร? ถ้าใช่คำหลักTabsคืออะไร ฉันพยายามทำสิ่งที่คล้ายกันบนแท็บ แต่ฉันดู alert.js และฉันไม่เห็นว่ามีalertDirectiveอยู่ตรงไหน
codenamezero

4
angularjs $compileProviderแนบคำต่อท้าย 'Directive' กับชื่อของคำสั่งของคุณเมื่อคุณลงทะเบียน ( $filterProviderเช่นเดียวกันกับคำต่อท้าย 'ตัวกรอง'); สำหรับวัตถุประสงค์ส่วนใหญ่สิ่งนี้จะมองไม่เห็น แต่เมื่อตกแต่งคุณจะต้องต่อท้ายคำต่อท้ายนี้ในคำสั่งที่คุณต้องการกำหนดเป้าหมาย ตัวอย่างเช่นtabDirectiveหรือtabsetDirectiveฯลฯ ไม่ได้มีการบันทึกไว้อย่างชัดเจนในทุกที่ที่ฉันสามารถพบได้ แต่นี่คือการอ้างอิงถึงพฤติกรรมที่คล้ายกัน$filterProviderอย่างน้อย: docs.angularjs.org/api/ng/provider/$filterProvider
JcT

2
ขอบคุณมาก @JcT คำตอบที่ดี นี่คือวิธีที่ถูกต้องที่จะไป และอย่างที่คุณพูดจุดเริ่มต้นที่ดีในการ "ตกแต่ง" คำสั่งของบุคคลที่สาม :)
John Bernardsson

1
@ValeraTumash: ขออภัยที่ตอบช้า ใช่ฉันคิดว่าการกำหนดค่าของคุณจะกลายเป็นก้อน อย่างไรก็ตามจาก Angular v1.3 ฉันเชื่อว่าคุณสามารถจัดหา a function(element, attributes)ให้กับ templateUrl ได้ คุณสามารถใช้สิ่งนี้สำหรับพฤติกรรมแบบไดนามิกบางอย่าง (ส่งคืนฟังก์ชัน templateUrl ดั้งเดิมหรือสตริง url ของคุณเองขึ้นอยู่กับแอตทริบิวต์ ฯลฯ ) อย่างไรก็ตามตอนนี้ ui.bootstrap ยังใช้ฟังก์ชันเดียวกันนี้เพื่อให้คุณtemplate-urlระบุแอตทริบิวต์ในคำสั่งดังนั้นคุณยังสามารถใช้สิ่งนั้นได้หากคุณพอใจที่จะจัดหาเส้นทางเทมเพลตโดยตรงผ่านแอตทริบิวต์องค์ประกอบคำสั่ง
JcT

27

คำตอบจากpkozlowski.opensourceมีประโยชน์มากและช่วยฉันได้มาก! ฉันปรับแต่งในเงื่อนไขของฉันให้มีไฟล์เดียวที่กำหนดการลบล้างเทมเพลตเชิงมุมทั้งหมดของฉันและโหลด JS ภายนอกเพื่อลดขนาดของข้อมูลลง

ในการดำเนินการนี้ให้ไปที่ด้านล่างของไฟล์ js ซอร์ส ui-bootstrap เชิงมุม (เช่นui-bootstrap-tpls-0.6.0.js) และค้นหาเทมเพลตที่คุณสนใจคัดลอกบล็อกทั้งหมดที่กำหนดเทมเพลตและวางลงในไฟล์ JS การแทนที่ของคุณ

เช่น

angular.module("template/alert/alert.html", []).run(["$templateCache", function($templateCache) {
  $templateCache.put("template/alert/alert.html",
     "      <div class='alert' ng-class='type && \"alert-\" + type'>\n" +
     "          <button ng-show='closeable' type='button' class='close' ng-click='close()'>Close</button>\n" +
     "          <div ng-transclude></div>\n" +
     "      </div>");
}]);

จากนั้นรวมไฟล์แทนที่ของคุณหลังจาก ui-bootstrap และคุณจะได้ผลลัพธ์เดียวกัน

รุ่นคดเคี้ยวของpkozlowski.opensource 's ตีเสียงดังปังhttp://plnkr.co/edit/iF5xw2YTrQ0IAalAYiAg?p=preview


1
ฉันใช้รูปแบบเดียวกันนี้และแม้ว่ามันจะได้ผล ฉันหวังว่าจะมีวิธีที่ดีกว่านี้ ฉันคิดว่าฉันชอบการกำหนดค่าในการโคลนมากกว่า
โบดีน

7

คุณสามารถใช้template-url="/app/.../_something.template.html"เพื่อลบล้างเทมเพลตปัจจุบันสำหรับคำสั่งนั้น

(ใช้งานได้ใน Accordion Bootstrap เป็นอย่างน้อย)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.