আর: ইউআই / এইচটিএমএল-ট্যাগগুলি থেকে কীভাবে মার্জিকভাবে কোড লজিককে আলাদা করতে হবে?


9

সমস্যা

যখন গতিশীলভাবে ইউআই-এলিমেন্টগুলি ( shiny.tag,, shiny.tag.list...) তৈরি করা হয় তখন প্রায়শই আমি আমার কোড যুক্তি থেকে এটি আলাদা করা এবং সাধারণত tags$div(...)লুপগুলি এবং শর্তাধীন বিবৃতিতে মিশ্রিত, নেস্টেড এর সংশ্লেষিত জগাখিচুড়ি শেষ করি difficult দেখতে বিরক্তিকর এবং কুরুচিপূর্ণ হওয়ার সময় এটি ত্রুটি-প্রবণও রয়েছে, যেমন এইচটিএমএল-টেম্পলেটগুলিতে পরিবর্তন করার সময়।

প্রজননযোগ্য উদাহরণ

ধরা যাক আমার কাছে নিম্নলিখিত তথ্য-কাঠামো রয়েছে:

my_data <- list(
  container_a = list(
    color = "orange",
    height = 100,
    content = list(
      vec_a = c(type = "p", value = "impeach"),
      vec_b = c(type = "h1", value = "orange")
    )
  ),
  container_b = list(
    color = "yellow",
    height = 50,
    content = list(
      vec_a = c(type = "p", value = "tool")
    )
  )  
)

আমি যদি এখন এই কাঠামোটি ইউআই-ট্যাগগুলির মধ্যে ঠেলাতে চাই তবে আমি সাধারণত এমন কিছু দিয়ে শেষ করি:

library(shiny)

my_ui <- tagList(
  tags$div(
    style = "height: 400px; background-color: lightblue;",
    lapply(my_data, function(x){
      tags$div(
        style = paste0("height: ", x$height, "px; background-color: ", x$color, ";"),
        lapply(x$content, function(y){
          if (y[["type"]] == "h1") {
            tags$h1(y[["value"]])
          } else if (y[["type"]] == "p") {
            tags$p(y[["value"]])
          }
        }) 
      )
    })
  )
)

server <- function(input, output) {}
shinyApp(my_ui, server)

যেমন আপনি দেখতে পাচ্ছেন, এটি ইতিমধ্যে আমার অদৃশ্য উদাহরণগুলির সাথে তুলনায় কিছুটা অগোছালো এবং এখনও কিছুই নয়।

পছন্দসই সমাধান

আমি আর এর জন্য একটি টেম্প্লেটিং ইঞ্জিনের কাছাকাছি এমন কিছু সন্ধান করার আশায় ছিলাম যা টেমপ্লেট এবং ডেটা আলাদাভাবে সংজ্ঞায়িত করতে দেয় :

# syntax, borrowed from handlebars.js
my_template <- tagList(
  tags$div(
    style = "height: 400px; background-color: lightblue;",
    "{{#each my_data}}",
    tags$div(
      style = "height: {{this.height}}px; background-color: {{this.color}};",
      "{{#each this.content}}",
      "{{#if this.content.type.h1}}",
      tags$h1("this.content.type.h1.value"),
      "{{else}}",
      tags$p(("this.content.type.p.value")),
      "{{/if}}",      
      "{{/each}}"
    ),
    "{{/each}}"
  )
)

পূর্ববর্তী প্রচেষ্টা

প্রথমত, আমি ভেবেছিলাম যে shiny::htmlTemplate()কোনও সমাধান প্রস্তাব দিতে পারে তবে এটি কেবল ফাইল এবং পাঠ্য স্ট্রিংয়ের সাথে কাজ করবে, shiny.tagগুলি নয় । আমি হুইস্কারের মতো কিছু আর-প্যাকেজগুলিতেও নজর রেখেছি তবে সেগুলির একই সীমাবদ্ধতা রয়েছে বলে মনে হয় এবং ট্যাগ বা তালিকার কাঠামো সমর্থন করে না।

ধন্যবাদ!


আপনি wwwফোল্ডারের অধীনে একটি সিএসএস ফাইল সংরক্ষণ করতে পারেন এবং তারপরে স্টাইল শিটগুলি প্রয়োগ করতে পারেন?
এমকেএ

সিএসএস প্রয়োগের ক্ষেত্রে অবশ্যই, তবে আমি একটি সাধারণ পদ্ধতির সন্ধান করছিলাম যা এইচটিএমএল-কাঠামো ইত্যাদির পরিবর্তনের জন্য অনুমতি দেয়
কমফোর্ট

সংযোজনে upvoting এবং মন্তব্য ছাড়া যোগ করার জন্য দরকারী কিছুই নয় othing আদর্শভাবে, htmlTemplate()শর্তসাপেক্ষ এবং লুপস আলা হ্যান্ডেলবারগুলি, গোঁফ, পাতলা করার অনুমতি দেয় ...
উইল

উত্তর:


2

আমি চকচকে এইচটিএমএল ট্যাগ (বা htmltoolsট্যাগ) উত্পাদন করে এমন ফাংশনগুলি ব্যবহার করে কম্পোজেবল এবং পুনরায় ব্যবহারযোগ্য UI উপাদান তৈরি করতে চাই । আপনার উদাহরণ অ্যাপ্লিকেশন থেকে, আমি একটি "পৃষ্ঠা" উপাদান এবং তারপরে দুটি জেনেরিক সামগ্রী পাত্রে সনাক্ত করতে পারি এবং তারপরে কিছু ফাংশন তৈরি করতে পারি:

library(shiny)

my_page <- function(...) {
  div(style = "height: 400px; background-color: lightblue;", ...)
}

my_content <- function(..., height = NULL, color = NULL) {
  style <- paste(c(
    sprintf("height: %spx", height),
    sprintf("background-color: %s", color)
  ), collapse = "; ")

  div(style = style, ...)
}

এবং তারপরে আমি আমার ইউআই কে এরকম কিছু দিয়ে রচনা করতে পারি:

my_ui <- my_page(
  my_content(
    p("impeach"),
    h1("orange"),
    color = "orange",
    height = 100
  ),
  my_content(
    p("tool"),
    color = "yellow",
    height = 50
  )
)

server <- function(input, output) {}
shinyApp(my_ui, server)

যে কোনও সময় যখন আমাকে কোনও উপাদানটির স্টাইলিং বা এইচটিএমএল টুইঙ্ক করতে হবে, আমি কেবল সেই উপাদানটি তৈরি করে এমন ফাংশনে চলে যাব।

এছাড়াও, আমি সেক্ষেত্রে সবেমাত্র ডেটা .ুকেছি। আমি মনে করি আপনার উদাহরণের ডেটা স্ট্রাকচারটি সত্যই ইউআই উদ্বেগের (স্টাইলিং, এইচটিএমএল ট্যাগ) সাথে ডেটা মিশ্রিত করে, যা কিছু সংশ্লেষিত-নেস ব্যাখ্যা করতে পারে। আমি দেখতে পাই কেবলমাত্র ডেটা হ্যাডার হিসাবে "কমলা", এবং বিষয়বস্তু হিসাবে "ইমপিচ" / "সরঞ্জাম"।

আপনার যদি আরও জটিল ডেটা থাকে বা আরও নির্দিষ্ট ইউআই উপাদানগুলির প্রয়োজন হয় তবে আপনি বিল্ডিং ব্লকগুলির মতো আবার ফাংশন ব্যবহার করতে পারেন:

my_content_card <- function(title = "", content = "") {
  my_content(
    h1(title),
    p(content),
    color = "orange",
    height = 100
  )
}

my_ui <- my_page(
  my_content_card(title = "impeach", content = "orange"),
  my_content(
    p("tool"),
    color = "yellow",
    height = 50
  )
)

আশা করি এইটি কাজ করবে. আপনি যদি আরও ভাল উদাহরণগুলির সন্ধান করেন, আপনি শাইনির ইনপুট এবং আউটপুট উপাদানগুলির (যেমন selectInput()), যা মূলত ফাংশন যা এইচটিএমএল ট্যাগগুলি স্পিট করে তার পিছনের উত্স কোডটি চেক করতে পারেন । একটি টেম্পলেটিং ইঞ্জিনও কাজ করতে পারে তবে আপনি ইতিমধ্যে যখন htmltoolsআর এর সম্পূর্ণ ক্ষমতা পেয়েছেন তখন আসল প্রয়োজন নেই


উত্তরের জন্য ধন্যবাদ! আমি এটির মতো এটিও করতাম, তবে এটি বেশ কার্যকর হয় যখন HTML এর বেশিরভাগ অংশ পুনরায় ব্যবহার করা যায় না। আমি অনুমান করি যে কোনও ধরণের টেম্পলেট-ইঞ্জিনই কেবলমাত্র একমাত্র কার্যকর সমাধান হবে: /
কমফোর্ট

1

হতে পারে আপনি মধ্যে খুঁজছেন বিবেচনা করতে পারে glue()এবং get()

পাওয়া():

get() স্ট্রিংগুলি ভেরিয়েবল / অবজেক্টে রূপান্তর করতে পারে।

সুতরাং আপনি সংক্ষিপ্ত করতে পারে:

if (y[["type"]] == "h1") {
    tags$h1(y[["value"]])
} else if (y[["type"]] == "p") {
    tags$p(y[["value"]])
}

প্রতি

get(y$type)(y$value)

(নীচের উদাহরণ দেখুন)।

আঠা ():

glue()এর বিকল্প সরবরাহ করে paste0()। আপনি যদি স্ট্রিংতে প্রচুর স্ট্রিং এবং ভেরিয়েবলকে সংক্ষিপ্ত করে রাখেন তবে এটি আরও পঠনযোগ্য হতে পারে। আমি ধরে নিয়েছি এটি আপনার পছন্দসই ফলাফলের বাক্য গঠনটিরও নিকটবর্তী দেখাচ্ছে।

পরিবর্তে:

paste0("height: ", x$height, "px; background-color: ", x$color, ";")

আপনি লিখবেন:

glue("height:{x$height}px; background-color:{x$color};")

আপনার উদাহরণটি এটিকে সহজতর করবে:

tagList(
  tags$div(style = "height: 400px; background-color: lightblue;",
    lapply(my_data, function(x){
      tags$div(style = glue("height:{x$height}px; background-color:{x$color};"),
        lapply(x$content, function(y){get(y$type)(y$value)}) 
      )
    })
  )
)

ব্যবহার:

library(glue)
my_data <- list(
  container_a = list(
    color = "orange",
    height = 100,
    content = list(
      vec_a = list(type = "p", value = "impeach"),
      vec_b = list(type = "h1", value = "orange")
    )
  ),
  container_b = list(
    color = "yellow",
    height = 50,
    content = list(
      vec_a = list(type = "p", value = "tool")
    )
  )  
)

বিকল্প:

আমি মনে করি এইচটিএমএলটিম্পলেটটি একটি ভাল ধারণা, তবে আরেকটি সমস্যা হ'ল অনাকাঙ্ক্ষিত শ্বেতস্পেস: https://github.com/rstudio/htMLtools/issues/19#issuecomment-252957684


আপনার ইনপুট জন্য ধন্যবাদ। আপনার কোডটি আরও কমপ্যাক্ট থাকাকালীন, এইচটিএমএল এবং যুক্তির মিশ্রণের বিষয়টি অবশেষ। : /
কমফোর্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.