Yii2 framework學習筆記(四) -- 第一個Widget

前臺最大的作用就是展示圖片,在用戶點擊後,可以將圖片彈出放大展示出來。


JQuery有兩個插件可以幫我們達到我們的目標

Magnific-Popup(http://dimsemenov.com/plugins/magnific-popup/): 用來製作彈出窗口。

Bricks(https://github.com/floo51/jquery-bricks): 多個圖片存在時,自動幫我們調整圖片大小,使其能夠排在同一行。


Magnific-Popup可以通過Composer進行安裝,在Yii目錄下的composer.json的require節點下添加內容

    "require": {
          ...
         "dimsemenov/magnific-popup": "*",
          ...
    },

然後在yii的目錄下啓動命令行工具,運行composer update。


安裝後的文件放置在vendor文件夾下,要應用到前臺頁面中,需要做成AssetBundle暴露出來。用AssetBundle的另外的好處是,可以幫我們處理依賴關係,並且可以只在需要的地方使用這些資源而不是每個頁面都把這些東西包裹進來增加負擔。


在frontend/assets下新建MangificPopupAsset.php,內容如下

namespace frontend\assets;

use yii\web\AssetBundle;

class MagnificPopupAsset extends AssetBundle
{
	public $sourcePath = '@vendor/dimsemenov/magnific-popup/dist';
	public $css = [
			'magnific-popup.css',
	];
	public $js = [
			'jquery.magnific-popup.js',
	];
	public $depends = [
			'yii\web\JqueryAsset',
	];
}

前期準備工作就緒,可以開始編寫widget。

新建frontend/widgets/ImagePopup.php(文件夾沒有則新建)

父類爲yii\base\Widget,主要需要複寫init和run方法。init用於初始化參數,run用來渲染成html代碼。

具體代碼如下


namespace frontend\widgets;

use yii\base\Widget;
use yii\base\InvalidConfigException;
use yii\helpers\Html;
use yii\helpers\ArrayHelper;
use yii\helpers\Json;
use yii\web\View;
use frontend\assets\MagnificPopupAsset;

class ImagePopup extends Widget {
	
	public $options;
	public $clientOptions = [];
	
	public function init() {
		if (!isset($this->options['src'])) {
			throw new InvalidConfigException("Image src must provided");
		}
		if (!isset($this->options['dest'])) {
			throw new InvalidConfigException("Popup destination must provided");
		}
		if (!isset($this->options['type'])) {
			if(isset($this->clientOptions['type'])) {
				$this->options['type'] = $this->clientOptions['type'];
			} else {
				$this->options['type'] = 'ajax';
			}
		}
		if (!isset($this->options['id'])) {
			$this->options['id'] = $this->getId();
		}
		if (!isset($this->options['wrapDiv'])) {
			$this->options['wrapDiv'] = true;
		}
		if (!isset($this->options['class'])) {
			$this->options['class'] = '';
		}
		$_options = [
			"items" => [ "src" => $this->options['dest'], ],
			"type" => $this->options['type'],
		];
		$this->clientOptions = ArrayHelper::merge($_options, $this->clientOptions);
		parent::init();
	}
	
	public function run() {
		$this->registerClientScript();
		if ($this->options['wrapDiv']) {
			$result = "<div id='" . $this->options['id'] . "' ";
			$result .= "class='" . $this->options['class'] . "'";
			$result .= ">";
			$result .= Html::img($this->options['src']);
			$result .= "</div>";
			return $result;
		} else {
 			return Html::img($this->options['src'], [
 					'id' => $this->options['id'],
 					'class' => $this->options['class'],				
 			]);
		}
	}
	
	protected function registerClientScript() {
		MagnificPopupAsset::register($this->view);
		$option = Json::encode($this->clientOptions);
		$script = "$('#" . $this->options['id'] . "').magnificPopup(" . $option . ")";
		$this->view->registerJs($script, View::POS_READY);
	}
}

然後就可以以如下方式調用該控件

echo ImagePopup::widget([	
	"options" => [
		"src" => "image/thumb/1.jpg",
		"dest" => $url,
	]
  ]);

其中src參數是展示的縮略圖,dest是點擊後彈出的東西,可以是一個url,以ajax調用,也可以是一個圖片地址,直接展示圖片。

彈出窗口的html源碼略。


然後引用另一個JQuery插件幫我們佈局圖片。

這個插件沒有提供composer安裝方式,直接下載js文件並放在frontend/web/js裏。

同樣,也需要用asset做層包裝,保證只在需要的地方引用該js。


frontend/assets/BricksAsset.php

namespace frontend\assets;

use yii\web\AssetBundle;

class BricksAsset extends AssetBundle
{
    public $basePath = '@webroot';
    public $baseUrl = '@web';
    public $css = [
    ];
    public $js = [
    	'js/jquery-bricks.min.js',
    ];
    public $depends = [
        'yii\web\JqueryAsset',
    ];
}

需要注意的是,之前引用web文件夾外的資源,使用的是sourcePath,yii框架會自動幫我們複製到web文件夾下。這次文件已經在web文件夾下了,則要使用basePath,防止重複複製。


然後在首頁頁面註冊該assetbundle,並調用我們之前寫的控件。

frontend/views/site/index.php

<?php

/* @var $this yii\web\View */
use frontend\widgets\ImagePopup;
use yii\helpers\Url;
use frontend\assets\BricksAsset;
use frontend\assets\MasonryAsset;

BricksAsset::register($this);
$this->title = Yii::t('common', Yii::$app->name);
?>

<div id="container" style="font-size:0px;">

<?php
  $url = Url::to(['ajax/image-popup']);
  echo ImagePopup::widget([	
	"options" => [
		"src" => "image/thumb/2.jpg",
		"dest" => $url,
		"wrapDiv" => false,
	]
  ]);
  echo ImagePopup::widget([
  		"options" => [
  				"src" => "image/thumb/5.jpg",
  				"dest" => $url,
  				"wrapDiv" => false,
  		]
  ]);
  echo ImagePopup::widget([
  		"options" => [
  				"src" => "image/thumb/6.jpg",
  				"dest" => $url,
  				"wrapDiv" => false,
  		]
  ]);
  echo ImagePopup::widget([
  		"options" => [
  				"src" => "image/thumb/7.jpg",
  				"dest" => $url,
  				"wrapDiv" => false,
  		]
  ]);
  echo ImagePopup::widget([
  		"options" => [
  				"src" => "image/thumb/8.jpg",
  				"dest" => $url,
  				"wrapDiv" => false,
  		]
  ]);
  echo ImagePopup::widget([
  		"options" => [
  				"src" => "image/thumb/9.jpg",
  				"dest" => $url,
  				"wrapDiv" => false,
  		]
  ]);
  echo ImagePopup::widget([
  		"options" => [
  				"src" => "image/thumb/10.jpg",
  				"dest" => $url,
  				"wrapDiv" => false,
  		]
  ]);
  echo ImagePopup::widget([
  		"options" => [
  				"src" => "image/thumb/11.jpg",
  				"dest" => $url,
  				"wrapDiv" => false,
  		]
  ]);
  ?>
</div>

<?php 
$script ="$('#container').bricks();";
$script .= "$(window).resize(function() {
  $('#container').data('bricks').layout();
});";
$this->registerJs($script);
?>


完成後效果及點擊彈出後效果如下。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章