let proxy = new Proxy(target, handler)
target – объект, обращения к которому надо перехватывать.
handler – объект с «ловушками»: функциями-перехватчиками для операций к target.
let my_arr = [];
// Proxy(target, handler)
let arr_proxy = new Proxy(my_arr, {
get(target, prop) {
console.log(`\n Getting ${prop}`);
console.log(`Perform needed actions after getting ${prop}`);
return target[prop];
},
set(target, prop, value) {
console.log(`\n Setting ${prop} ${value}`);
console.log(`Perform needed actions after setting ${prop} ${value}`);
target[prop] = value;
return true;
}
})
arr_proxy.push('dsfdgdf')
SELECT c.category_id, COUNT(r.record_id) AS records
FROM category AS c
LEFT JOIN records AS r USING(record_id)
GROUP BY c.record_id
HAVING records > 5
SELECT *
FROM news n
INNER JOIN news_comments nc ON n.news_id = nc.news_id
GROUP BY n.news_id
ORDER BY COUNT(nc.comment_id) DESC, n.date DESC
News::find()->where(['news.visibility'=>1])
->innerJoin(['nc' => NewsComments::tableName()], 'nc.news_id = news.id')
->groupBy('news.id')
->orderBy('COUNT(nc.id) DESC, news.date DESC');
WHERE MONTH(`date`) = MONTH(NOW()) AND YEAR(`date`) = YEAR(NOW())
SomeModel::find()->andWhere("MONTH(`date`) = MONTH(NOW()) AND YEAR(`date`) = YEAR(NOW())")->all();
$.ajax({
url: '/demo.php',
type: 'POST',
data: data,
success: function (html) {
$goods_list.empty().append(html);
rivets.bind($goods_list, model);
toTopAfterAjaxUpdatePagination();
}
});
var $ = jQuery;
$(function(){
var $goods_list = $('ul.goods__list'),
model = {
data: JSON.parse(localStorage.getItem('g_zakazi')) || {
title: 'Welcome',
//juzer_id: $('#juzer-id').text(),
subtotal: 0,
zakazi: []
},
controller: controller
};
rivets.bind(document.querySelector('#rivetsSpace'), model);
$('.goods__pagination').on('click', '.goods__page', function(){
console.log('Клик по пагинации');
var data = { id: $(this).text() };
$.ajax({
url: '/demo.php',
type: 'POST',
data: data,
success: function (html) {
//console.log(data);
$goods_list.empty().append(html);
rivets.bind($goods_list, model);
toTopAfterAjaxUpdatePagination();
}
});
});
});
function returnFalse(){
console.log('Выходим');
return false;
}
var controller = {
onAtbClick: function(e, model) {
var ID = $(this).data("id");
var goods = model.data.zakazi.filter(function (goods) {
return goods.ID === ID;
})[0];
if (goods) {
goods.quantity++;
returnFalse();
} else {
model.data.zakazi.push({
ID: ID,
quantity: 1
});
}
model.controller.updatePrice(model.data);
model.controller.saveData(model.data);
},
updatePrice: function(data) {
var zakazi = data.zakazi,
product,
subtotal = 0;
data.subtotal = subtotal;
},
removeGoods: function(e, model) {
e.stopImmediatePropagation();
var index = model.index,
zakazi = model.data.zakazi;
zakazi.splice(index, 1);
model.controller.saveData(model.data);
},
saveData: function(data) {
localStorage.setItem( 'g_zakazi', JSON.stringify( data ) );
}
}
function toTopAfterAjaxUpdatePagination() {
var scrollGoods = $('section.goods').offset().top;
$(document).scrollTop(scrollGoods - 50);
}
rivets.formatters.length = function(val) {
return val.length;
};
window.items = [
{ id: 1 },
{ id: 2 },
{ id: 3 },
...
]
model.$goods_list.append( controller.processGoods(window.items, model) );
...
var controller = {
processGoods: function(data, model) {
var elements = new Array(data.length),
temp_fragment = document.createDocumentFragment();
for (var i = 0; i < data.length; i++) {
elements[ i ] = model.controller.createElementFromTemplate('goods__item', model);
rivets.bind(elements[i], Object.assign({ item: data[i] }, model));
temp_fragment.appendChild( elements[ i ] );
}
return temp_fragment;
},
createElementFromTemplate: function(item, model) {
return document.importNode(model.templates[ item ].content.children[0], true);
},
...
}
$('.goods__pagination').on('click', '.goods__page', function() {
var data = {
id: $(this).text()
};
$.ajax({
url: '/demo.php',
type: 'POST',
data: data,
dataType: 'json',
success: function(data) {
model.$goods_list.empty().append( controller.processGoods(data, model) );
toTopAfterAjaxUpdatePagination();
}
});
});
CKEDITOR.replace( 'editor1', {
// Define the toolbar: http://docs.ckeditor.com/#!/guide/dev_toolbar
// The full preset from CDN which we used as a base provides more features than we need.
// Also by default it comes with a 3-line toolbar. Here we put all buttons in a single row.
toolbar: [
{ name: 'document', items: [ 'Print' ] },
{ name: 'clipboard', items: [ 'Undo', 'Redo' ] },
{ name: 'styles', items: [ 'Format', 'Font', 'FontSize' ] },
{ name: 'basicstyles', items: [ 'Bold', 'Italic', 'Underline', 'Strike', 'RemoveFormat', 'CopyFormatting' ] },
{ name: 'colors', items: [ 'TextColor', 'BGColor' ] },
{ name: 'align', items: [ 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ] },
{ name: 'links', items: [ 'Link', 'Unlink' ] },
{ name: 'paragraph', items: [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote' ] },
{ name: 'insert', items: [ 'Image', 'Table' ] },
{ name: 'tools', items: [ 'Maximize' ] },
{ name: 'editing', items: [ 'Scayt' ] }
],
// Since we define all configuration options here, let's instruct CKEditor to not load config.js which it does by default.
// One HTTP request less will result in a faster startup time.
// For more information check http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-customConfig
customConfig: '',
// Sometimes applications that convert HTML to PDF prefer setting image width through attributes instead of CSS styles.
// For more information check:
// - About Advanced Content Filter: http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter
// - About Disallowed Content: http://docs.ckeditor.com/#!/guide/dev_disallowed_content
// - About Allowed Content: http://docs.ckeditor.com/#!/guide/dev_allowed_content_rules
disallowedContent: 'img{width,height,float}',
extraAllowedContent: 'img[width,height,align]',
// Enabling extra plugins, available in the full-all preset: http://ckeditor.com/presets-all
extraPlugins: 'tableresize,uploadimage,uploadfile',
/*********************** File management support ***********************/
// In order to turn on support for file uploads, CKEditor has to be configured to use some server side
// solution with file upload/management capabilities, like for example CKFinder.
// For more information see http://docs.ckeditor.com/#!/guide/dev_ckfinder_integration
// Uncomment and correct these lines after you setup your local CKFinder instance.
// filebrowserBrowseUrl: 'http://example.com/ckfinder/ckfinder.html',
// filebrowserUploadUrl: 'http://example.com/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Files',
/*********************** File management support ***********************/
// Make the editing area bigger than default.
height: 800,
// An array of stylesheets to style the WYSIWYG area.
// Note: it is recommended to keep your own styles in a separate file in order to make future updates painless.
contentsCss: [ 'https://cdn.ckeditor.com/4.6.1/full-all/contents.css', 'mystyles.css' ],
// This is optional, but will let us define multiple different styles for multiple editors using the same CSS file.
bodyClass: 'document-editor',
// Reduce the list of block elements listed in the Format dropdown to the most commonly used.
format_tags: 'p;h1;h2;h3;pre',
// Simplify the Image and Link dialog windows. The "Advanced" tab is not needed in most cases.
removeDialogTabs: 'image:advanced;link:advanced',
// Define the list of styles which should be available in the Styles dropdown list.
// If the "class" attribute is used to style an element, make sure to define the style for the class in "mystyles.css"
// (and on your website so that it rendered in the same way).
// Note: by default CKEditor looks for styles.js file. Defining stylesSet inline (as below) stops CKEditor from loading
// that file, which means one HTTP request less (and a faster startup).
// For more information see http://docs.ckeditor.com/#!/guide/dev_styles
stylesSet: [
/* Inline Styles */
{ name: 'Marker', element: 'span', attributes: { 'class': 'marker' } },
{ name: 'Cited Work', element: 'cite' },
{ name: 'Inline Quotation', element: 'q' },
/* Object Styles */
{
name: 'Special Container',
element: 'div',
styles: {
padding: '5px 10px',
background: '#eee',
border: '1px solid #ccc'
}
},
{
name: 'Compact table',
element: 'table',
attributes: {
cellpadding: '5',
cellspacing: '0',
border: '1',
bordercolor: '#ccc'
},
styles: {
'border-collapse': 'collapse'
}
},
{ name: 'Borderless Table', element: 'table', styles: { 'border-style': 'hidden', 'background-color': '#E6E6FA' } },
{ name: 'Square Bulleted List', element: 'ul', styles: { 'list-style-type': 'square' } }
]
} );
class Tags extends ActiveRecord
{
public function getPages()
{
return $this->hasMany(Statjiblog::className(), ['id' => 'post_id'])->viaTable('{{%statjiblogtags}}', ['tag_id' => 'id']);
}
}
public function actionPage($slug){
$model = Tags::find()->andWhere(['slug'=>$slug])->one();
foreach($model->pages as $page){
echo $page->title;
}
}
db: {
users: {
id: 111,
name: 'Rostislav',
room: 8888,
},
rooms: {
id: 8888,
messages: [...],
owner: 111,
public: true
}
}
Allow-Control-Allow-Origin: *
processData: false
в параметры вашего ajax-запроса.$.ajax({
type: "POST",
url: api_url,
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
processData: false,
data: JSON.stringify(pd),
success: function (result) {
// ...
}
});