2016-04-05 23 views
0

Alt dizinler olarak birçok, ayrı "site" oluşturan bir uygulama üzerinde çalışıyorum. /client/1, /client/2, vb. Bunların her biri için, uygulamanın yönetim bölümünde iki renk değeri belirtilebilir.Ember uygulamasında Sass değişkenlerine veri enjekte etme

İlk olarak Ember tarafından arka uç API'ye gönderilen ve sonra önişlem için bir SCSS dosyasına alınan değerleri enjekte etme yöntemi olup olmadığını bilmek ister misiniz?

Şimdiye kadar hiç bir çözüm bulamadım.

+0

Hayır, bu mümkün değil. Ember uygulamanız çalışmaya başladığında ve kullanıcı verilerini çalıştırabildiğinde, sass dosyaları zaten css olarak derlenmiştir. Yani şu anda değişkenleri değiştirmenin bir yolu yoktur. –

+0

@GennadyDogaev https://github.com/medialize/sass.js/ – typeoneerror

+0

Olası http: // stackoverflow kopyası.com/questions/17787845/how-to-control-sass-variable-with-javascript – cimmanon

cevap

2

Ember/Rails uygulamasında, veritabanındaki bazı ayarlara göre her istemci için CSS dosyaları oluşturuyoruz. Örneğin, bizim Tenant modeli iki alan vardır:

{ 
    primary_color: 'ff3300', 
    secondary_color: '00ff00' 
} 

Biz açığa yolları

scope '/stylesheets', format: 'css' do 
    get 'tenant/:tenant_id', to: 'stylesheets#tenant_css' 
end 

Ve kontrolör şöyle görünür:

class StylesheetsController < ApplicationController 

    layout nil 

    rescue_from 'ActiveRecord::RecordNotFound' do 
    render nothing: true, status: 404 
    end 

    def tenant_css 
    # fetch model 
    tenant = Tenant.find(params[:tenant_id]) 

    # cache the css under a unique key for tenant 
    cache_key = "tenant_css_#{tenant.id}" 

    # fetch the cache 
    css = Rails.cache.fetch(cache_key) do 
     # pass sass "params" 
     render_css_for 'tenant', { 
     primary_color: tenant.primary_color, 
     secondary_color: tenant.secondary_color 
     } 
    end 

    render_as_css css 
    end 

    protected 

    # our renderer, could also add a custom one, but simple enough here 
    def render_as_css(css) 
    render text: css, content_type: 'text/css' 
    end 

    # looks for a template in views/stylesheets/_#{template}.css.erb 
    def render_css_for(template, params = {}) 
    # load the template, parse ERB w params 
    scss = render_to_string partial: template, locals: { params: params } 
    load_paths = [Rails.root.join('app/assets/stylesheets')] 
    # parse the rendered template via Saas 
    Sass::Engine.new(scss, syntax: :scss, load_paths: load_paths).render 
    end 

end 

Bu şekilde, /stylesheets/tenant/1.css bağlanabilirsiniz Sass motorunu kullanarak kiracı için CSS oluşturacak. Bu durumda

, görünümler/stil/_tenant.css.erb içinde, böyle bir şey olurdu (bir ERB dosyasıdır ama şimdi orada Sass kullanabilirsiniz):

@import "bootstrap-buttons"; 

<% if params[:primary_color].present? %> 
    $primary-color: <%= params[:primary_color] %>; 
    h1, h2, h3, h4, h5, h6 { 
    color: $primary-color; 
    } 
<% end %> 

<% if params[:secondary_color].present? %> 
    $secondary-color: <%= params[:secondary_color] %>; 
    a { 
    color: $secondary-color; 
    &:hover { 
     color: darken($secondary-color, 10%); 
    } 
    } 
<% end %> 

You' Şimdi Sass motoru için stil sayfası yolunda bir şey almak için @import kullanabileceğimi unutmayın (bu durumda, Bootstrap Sass lib'in bazı yardımcılarını kullanabilirim).

CSS yedekleme Modeliniz güncellendiğinde Sen önbellek silin önbellek temizleyici çeşit isteyeceksiniz

:

class Tenant < ActiveRecord::Base 
    after_update do 
    Rails.cache.delete("tenant_css_#{id}") 
    end 
end 

Yani bu Özetle Raylar tarafı.

Ember'de, tahminim, stil sayfasını bir ID'ye dayalı olarak yüklemek isteyeceksiniz, böylece stil sayfası "index.html" ye kodlanamaz. Ember CSS Routes addon size iyi hizmet edebilir, ancak sadece başlığa <link> ekler, bu nedenle CSS stil sayfalarını istediğiniz zaman değiştirmelisiniz, bu işe yaramaz. Ben şöyle bir rotada bu sorunu var: Ayrıca bir <link> etiketi biçimlendirmek ve "solucan deliği" haline işlemek için Ember Wormhole kullanmak sonra <head> boş öğesi ekleyin ve olabilir

afterModel(model, transition) { 
    // dynamically form the URL here 
    const url = "/stylesheets/tenant/1"; 

    // build link object 
    const $link = $('<link>', { rel: 'stylesheet', href: url, id: 'tenant-styles' }); 

    // resolve the promise once the stylesheet loads 
    const promise = new RSVP.Promise((resolve, reject) => { 
    $link.on('load',() => { 
     $link.appendTo('head'); 
     resolve(); 
    }).on('error',() => { 
     // resolve anyway, no stylesheet in this case 
     resolve(); 
    }); 
    }); 

    return promise; 
}, 

// remove the link when exiting 
resetController(controller, isExiting, transition) { 
    this._super(...arguments); 
    if (isExiting) { 
    $('#tenant-styles').remove(); 
    } 
} 

.

Düzenleme

Ayrıca rendering Sass directly in the client application bakmak olabilir. İki renk kadar basit bir şey için, özellikle bir hizmet görevlisi kullandıysanız ya da sonuçları önbelleğe almaya benzer bir performansa sahipseniz, bu çok fazla performans etkisi yaratmaz.