怎么將圖片上傳封裝成指令悦即?

一吮成、背景介紹

如果我們想實現(xiàn)圖片上傳功能,其中需要包含以下功能
*點擊按鈕上傳圖片
*圖片能在本地預(yù)覽
*顯示圖片信息辜梳,顯示上傳進度
*點擊上傳按鈕上傳到服務(wù)器
*點擊刪除按鈕粱甫,刪除。
*上傳按鈕只能按一次
現(xiàn)在我們需要把它用directive自定義指令封裝起來作瞄。
為什么要封裝呢茶宵?這個圖片上傳插件如果需要多次運用的話,用自定義指令封裝后能減少大量代碼宗挥。

二节预、知識剖析

關(guān)于指令,網(wǎng)上有很多資料属韧,這里就簡單說一下安拟。
angular指令本質(zhì)上就是AngularJs擴展具有自定義功能的html元素的途徑。
angular指令本質(zhì)上就是AngularJs擴展具有自定義功能的html元素的途徑宵喂。
內(nèi)置指令糠赦,打包在AngularJs內(nèi)部的指令,所有內(nèi)部指令的命名空間 都使用ng作為前綴锅棕,所以在寫自定義指令的時候拙泽,避免用ng作為指令命名的前綴。
創(chuàng)建指令的方式有四種裸燎,在指令里用 restrict屬性控制:
*E:元素
*A:屬性
*C:css類
*M:注釋
向指令中傳遞數(shù)據(jù)顾瞻,用template屬性
directive 在使用隔離 scope 的時候,提供了三種方法同隔離之外的地方交互:
*@ 綁定一個局部 scope 屬性到當前 dom 節(jié)點的屬性值德绿。結(jié)果總是一個字符串荷荤,因為 dom 屬性是字符串退渗。
*= 通過 directive 的 attr 屬性的值在局部 scope 的屬性和父 scope 屬性名之間建立雙向綁定。
*& 提供一種方式執(zhí)行一個表達式在父 scope 的上下文中蕴纳。如果沒有指定 attr 名稱会油,則屬性名稱為相同的本地名稱。(其實說白了古毛,就是可以使用在父scope中定義的函數(shù)翻翩。)
replace:是否用模板替換當前元素。
true : 將指令標簽替換成temple中定義的內(nèi)容,頁面上不會再有標簽稻薇;
false :則append(追加)在當前元素上嫂冻,即模板的內(nèi)容包在標簽內(nèi)部。默認false塞椎。

三絮吵、常見問題

如何實現(xiàn)封裝?

四忱屑、解決方案

見代碼

五蹬敲、編碼實戰(zhàn)

//template
<form name="myForm" class="col-lg-10">
    <div class="row">
        <div class="col-lg-10 col-sm-12">
            <div class="row">
                <label class="col-md-2 col-sm-12 titles">{{labelName}}</label>
                <div class="col-lg-12" ng-if="uploader">
                    <label class="btn-pic" for="{{imgId}}" style="float:left;">
                        選擇文件
                    </label>
                    <input type="file" accept="image/*"
                           name="file" id="{{imgId}}"
                           style="display: none;"
                           nv-file-select=""
                           uploader="uploader"
                           multiple="">
                    <label style="line-height:.3rem;">(圖片最大為1m)</label>
                </div>
            </div>
            <div class="row">
                <div class="col-lg-12">
                    <!--圖片預(yù)覽-->
                    <img style="max-width: 100%;" ng-src="{{imageUrl}}">
                </div>
            </div>
        </div>
    </div>

    <div class="row">
        <div class="col-lg-10">
            <!-----上傳圖片插件----->
            <table class="table">
                <thead>
                <tr>
                    <th>圖片名</th>
                    <th>文件大小</th>
                    <th>進度</th>
                    <th>狀態(tài)</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody>
                <tr ng-repeat="item in uploader.queue">
                    <td style="word-break:break-all">
                        <strong>{{ item.file.name }}</strong>
                    </td>
                    <td nowrap>{{ item.file.size/1024/1024|number:2 }} MB</td>
                    <td>
                        <div class="progress" style="margin-bottom: 0;">
                            <div class="progress-bar" role="progressbar"
                                 ng-style="{ 'width': item.progress + '%' }"></div>
                        </div>
                    </td>
                    <td class="text-center">
                        <span ng-show="item.isSuccess"><i class="glyphicon glyphicon-ok"></i></span>
                        <span ng-show="item.isCancel"><i class="glyphicon glyphicon-ban-circle"></i></span>
                        <span ng-show="item.isError"><i class="glyphicon glyphicon-remove"></i></span>
                    </td>
                    <td>
                        <button type="button" class="btn btn-success btn-xs" ng-click="item.upload()"
                                ng-disabled="item.isReady || item.isUploading || item.isSuccess">
                            <span class="glyphicon glyphicon-upload"></span> Upload
                        </button>
                        <button type="button" class="btn btn-warning btn-xs" ng-click="item.cancel()"
                                ng-disabled="!item.isUploading">
                            <span class="glyphicon glyphicon-ban-circle"></span> Cancel
                        </button>
                        <button type="button" class="btn btn-danger btn-xs" ng-click="item.remove()">
                            <span class="glyphicon glyphicon-trash"></span> Remove
                        </button>
                    </td>
                </tr>
                </tbody>
            </table>
        </div>
    </div>
</form>
//directive
angular.module("myApp")
    .directive("uploadFile", function (FileUploader) {
        return {
            restrict: "EA",
            templateUrl: "html/fileUpload.html",
            scope: {
                labelName:"@",
                imageUrl:"=ngModel",
                imgId:"@"
            },
            replace: true,
            link: function (scope,ele,attrs) {
                // 上傳圖片插件
                scope.uploader = new FileUploader({
                    url: "/carrots-admin-ajax/a/u/img/task",
                    queueLimit: 1
                });
                scope.uploader.onSuccessItem = function (fileItem, response,status,headers) {
                    scope.imageUrl = response.data.url;
                };
            }
            //link或者controller都可以達到效果
            // controller:function ($scope) {
            //     // 上傳圖片插件
            //     $scope.uploader = new FileUploader({
            //         url: "/carrots-admin-ajax/a/u/img/task",
            //         queueLimit: 1
            //     });
            //     $scope.uploader.onSuccessItem = function (fileItem, response,status,headers) {
            //         $scope.imageUrl = response.data.url;
            //     };
            // }
        }
    });
//html
<upload-file ng-model="params.img" img-id="img" label-name="article圖片"></upload-file>

六、擴展思考

指令中controller跟link的區(qū)別?當我們每次想要擴展個自定義指令時莺戒,應(yīng)該用哪個伴嗡?
簡單來說,優(yōu)先使用link从铲。事實上瘪校,這兩個都可以獲取到作用域,元素名段,屬性等引用阱扬,也都會執(zhí)行一次。
控制器可以暴露一個API伸辟,而link可以通過require與其他的指令控制器交互麻惶。
所以如果要開放出一個API給其他指令用就寫在controller中,否則寫在link中信夫。

七窃蹋、更多討論

討論點一、去掉template頁中第7行的「ng-if="uploader"」静稻,使用link就會報錯警没,使用controller則正常,這是為什么振湾?
討論點二杀迹、如何上傳多張圖片?
討論點三押搪、&方法該如何應(yīng)用树酪?

八浅碾、參考文獻

參考一:angular自定義指令詳解

參考二:Angular File Upload

參考三:angular-file-upload 中文API

參考四:ng指令中controller與link的區(qū)別

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市嗅回,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌摧茴,老刑警劉巖绵载,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異苛白,居然都是意外死亡娃豹,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門购裙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來懂版,“玉大人,你說我怎么就攤上這事躏率∏耄” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵薇芝,是天一觀的道長蓬抄。 經(jīng)常有香客問我,道長夯到,這世上最難降的妖魔是什么嚷缭? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮耍贾,結(jié)果婚禮上阅爽,老公的妹妹穿的比我還像新娘。我一直安慰自己荐开,他們只是感情好付翁,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著晃听,像睡著了一般胆敞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上杂伟,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天移层,我揣著相機與錄音,去河邊找鬼赫粥。 笑死观话,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的越平。 我是一名探鬼主播频蛔,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼灵迫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了晦溪?” 一聲冷哼從身側(cè)響起瀑粥,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎三圆,沒想到半個月后狞换,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡舟肉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年修噪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片路媚。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡黄琼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出整慎,到底是詐尸還是另有隱情脏款,我是刑警寧澤,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布裤园,位于F島的核電站弛矛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏比然。R本人自食惡果不足惜丈氓,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望强法。 院中可真熱鬧万俗,春花似錦、人聲如沸饮怯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蓖墅。三九已至库倘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間论矾,已是汗流浹背教翩。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留贪壳,地道東北人饱亿。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親彪笼。 傳聞我的和親對象是個殘疾皇子钻注,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353